Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2011, 19:43   #1
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию Как можно закрепить за окном класс(указатель на него)

Как можно закрепить за окном класс(указатель на него), а потом вытаскивать класс(указатель) в процедуре обработки событий.
Код:
function WinProc  ( HWND, MSG, WPR, LPR: Longint ) : Longint; stdcall;
var
  App:TApp;
begin
  //??
  App.WinProc  (HWND, MSG, WPR, LPR);

end;
Что за название темы "hwnd + userdata + winpoc" ?
Читаем правила раздела...

Последний раз редактировалось mihali4; 06.11.2011 в 15:04.
Warn вне форума Ответить с цитированием
Старый 05.11.2011, 19:50   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

1)
WNDCLASSEX.cbClsExtra+GetClassLongPtr
Hу и Set в начале.
2)GetWindowLong с параметром GWL_USERDATA(можно по первому принципу аналогичное организовать)
и естественно в начале Set-версия.
3)Вести массив/список соответствия, хендл-объект
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.11.2011, 20:19   #3
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

Второй вариант пожалуй удобнее, но я не пойму как мне и куда запихнуть данные? у ф-и SetWindowLong последний параметр число, а не указатель на что-либо( прилагаю короткое описание интерфейсов классов и в последнем блоке кодов то как я пытаюсь реализовать это безобразие(.

Код:
unit App.Window;

interface

uses Windows, Messages;

const Default_Window_Width : Cardinal = 1024;
const Default_Window_Height : Cardinal = 768;

// Указатель на ф-ю класса
type procEvent = procedure ( wpr, lpr : Longint ) of object;

type TWindow = class
	public
  	Wc : TWndClass;
    Msg : TMsg;
  	Instance : HWnd;
    Handle : HWnd;
    Width : Integer;
    Height : Integer;
    X : Integer;
    Y : Integer;
    DoMouse : procEvent;
    DoKeyboard : procEvent;

    constructor Create ();overload;
    constructor Create (const Width, Height : Integer; const Caption : string='View');overload;
    procedure DoEvents();
    procedure Show ( Visible : Boolean );
    procedure SetPosition ( const x, y : Integer );
    procedure SetCaption ( const Title : String );
		destructor Destroy (); override;
end;

	function WindowCallBack ( HWND, MSG, WPR, LPR: Longint ) : Longint; stdcall;

implementation
...
Код:
unit App;

interface

uses Windows, Messages, App.Window;

type TApp = class
    private
    	procedure InitWindow();
      procedure InitDirect3D();

    public
    	IsRunning : Boolean;
      MainWindow : TWindow;

      constructor Create();
      procedure InitApplication();
      procedure Process();
      procedure MouseEvent( wpr, lpr : Longint );
      procedure KeyboardEvent( wpr, lpr : Longint );
      function WindowCallBack ( HWND, MSG, WPR, LPR: Longint ) : Longint; stdcall;
      destructor Destroy();
  end;
...
Код:
procedure TApp.InitWindow();
begin
	if (MainWindow <> nil) then
  	MainWindow.Destroy();

  MainWindow := TWindow.Create();
  SetWindowLong(MainWindow.Handle, GWL_USERDATA, self???)
end;
Warn вне форума Ответить с цитированием
Старый 05.11.2011, 21:56   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вот
А вообще приведение типов.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 05.11.2011 в 21:58.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.11.2011, 00:07   #5
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

ничего не получается(

записываю так
Код:
procedure TApp.InitWindow();
begin
	if (MainWindow <> nil) then
  	MainWindow.Destroy();

  MainWindow := TWindow.Create();
	SetWindowLongPtr(MainWindow.Handle, GWLP_USERDATA, Integer(@self));

end;
читаю так
Код:
function WindowCallBack ( HWND, MSG, WPR, LPR : Longint ):Longint; stdcall;
var
	AppInst : PApp;
begin
  AppInst:=Pointer(GetWindowLongPtr(HWND, GWLP_USERDATA));
  result := AppInst^.WindowCallBack(HWND, MSG, WPR, LPR);

  end;
Вложения
Тип файла: rar Exe01.rar (11.3 Кб, 8 просмотров)
Warn вне форума Ответить с цитированием
Старый 06.11.2011, 10:47   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Классы итак хранятся по указателю.
Потому:
Код:
procedure TApp.InitWindow();
begin
	if (MainWindow <> nil) then
  	MainWindow.Destroy();

  MainWindow := TWindow.Create();
	SetWindowLongPtr(MainWindow.Handle, GWLP_USERDATA, Integer(self));
end;
Код:
function WindowCallBack ( HWND, MSG, WPR, LPR : Longint ):Longint; stdcall;
var
	AppInst : TApp;
begin
  AppInst:=TApp(GetWindowLongPtr(HWND, GWLP_USERDATA));
  result := AppInst.WindowCallBack(HWND, MSG, WPR, LPR);
  end;
А вообще вы уверены что вам нужен класс TApp, а не TWindow?
По логике поидее окно должно этим заниматся
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.11.2011, 11:32   #7
Warn
Форумчанин
 
Аватар для Warn
 
Регистрация: 03.11.2011
Сообщений: 230
По умолчанию

11:32
Код:
SetWindowLongPtr(MainWindow.Handle, GWLP_USERDATA, Integer(self));
не помогло( читает nil, данных все так же нету и вылетает.
Цитата:
А вообще вы уверены что вам нужен класс TApp, а не TWindow?
По логике поидее окно должно этим заниматся
возможно я неправильно продумал архитектуру взаимодействий. У меня создается единственный экземпляр TApp. в интерфейсной части которого в Public секции имеется TWindow и для обработки событий окна есть внешняя ф-я winproc, от которой я хочу события передавать внутрь класса TApp и там дальше разруливать их. Поскольку остальные объекты тоже думал включать в состав TApp т.е. все пространство действий это область видимости которая не выходит за TApp его ф-ии. я хз а как окно этим должно заниматься? пробовал с глобальной переменной TApp, которая будет видна во внешнем winproc, но замучили - кольцевые переопределения или что-то в этом роде.


14:45
Наконец-то решил проблему!
Оказывается ф-я WinAPI когда создает окно
Код:
Handle:=CreateWindow('WinAppClass', Default_Window_Title, WS_EX_TOPMOST, 0, 0, Width, Height, 0, 0, Instance, @WindowCallBack);
SetWindowLong(self.Handle, GWL_USERDATA, Integer(self));
первым делом бежит в winproc указанный в зарегистрированной выше структуре wc.
и пытается обработать это событие. а там у меня был код, ожидающий что указатель на UserData уже установлен.
Код:
function WindowCallBack ( HWND, MSG, WPR, LPR : Longint ):Longint; stdcall;
var AppInst : PApp;
begin
  AppInst:=Pointer(GetWindowLongPtr(HWND, GWLP_USERDATA));
  AppInst.WinProc(HWND, MSG, WPR, LPR); //Вылет тут поскольку AppInst = nil
  result:=defwindowproc(hwnd,msg,wpr,lpr);
end;
добавил проверку на nil ! все работает и передает в класс события окна.
Код:
function WindowCallBack ( HWND, MSG, WPR, LPR : Longint ):Longint; stdcall;
var AppInst : PApp;
begin
  AppInst:=Pointer(GetWindowLongPtr(HWND, GWLP_USERDATA));
  if (AppInst<>nil) then 
  begin
  AppInst.WinProc(HWND, MSG, WPR, LPR);
  end;
  result:=defwindowproc(hwnd,msg,wpr,lpr);
end;
Красные жирные циферки видны ?
Это время, когда вы отправляли свои сообщения друг за другом, подряд.
Читаем правила раздела.
По правилам это приравнивается к флуду.

Последний раз редактировалось mihali4; 06.11.2011 в 15:28.
Warn вне форума Ответить с цитированием
Старый 06.11.2011, 15:05   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
первым делом бежит в winproc указанный в зарегистрированной выше структуре wc
Ну да..WM_CREATE.

Я просто проверить не мог, у меня последняя Делфи улетела...

Я бы лично делал бы нечто подобное так:
Код:
class TWindow=class
 protected
  function WndProc(uMsg:UINT;wParam,lParam:integer):integer;virtual abstract;
 end;

---------------------

function ClassWndProc(hwnd:THandle;uMsg:UINT;wParam,lParam:integer):integer;stdcall;
var W:TWindow;
begin
 if(uMsg=WM_CREATE)
  then
   begin
    W:=TWindow((LPCREATESTRUCT(lParam))^.lpCreateParams);
    W.Handle:=hwnd;
    SetWindowLongPtr(hwnd,GWLP_USERDATA,W);//про приведение типов не помню
   end
  else
   begin
    W:=TWindow(GetWindowLongPtr(hwnd,GWLP_USERDATA));
   end;
 Result:=W.WndProc(uMsg,wParam,lParam);
end;
Ну и естественно для этого надо в последнем параметре CreateWindowEx передавать наш TWindow объект.
Код:
CreateWindowEx(...,Pointer(W));
Правда это совсем в крадце, ибо там есть нюансы
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 07.11.2011 в 08:28.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
не создается указатель на класс CodeNOT Общие вопросы C/C++ 4 04.01.2011 12:10
Указатель на абстрактный класс zhenya.ya Общие вопросы C/C++ 0 11.11.2010 23:51
[C++] Указатель на производный класс в базовом Student_IT Общие вопросы C/C++ 3 06.06.2010 07:06
Указатель на класс Колючка* Общие вопросы Delphi 8 21.01.2010 07:38
Вернут указатель на базовый класс Crucian Общие вопросы C/C++ 2 08.11.2007 18:10