-
Пишу игровой движок. У класса движка есть несколько полей, которые должны изменяться при получении того или иного сообщения. Но т.к. WndProc вне классовая процедура, то поля класса в нём не изменишь. Как поместить туда, эти самые поля? Не хотелось бы пользоваться глобальными переменными, а потом уже через них присваивать значения полям класса. (Но пока так)
-
Запиши в данные окна указатель на класс, а в WndProc получай эти данные через HWND
-
Лично я использую GWL_USERDATA SetWindowLong GetWindowLong
-
> @!!ex © (22.07.09 20:09) [2]
Что-то не понял, как с их помощью, это сделать.
-
Разжую: ПРи создании окна делаем: SetWindowLong(Wnd,GWL_USERDATA,Class);
В WndProc: Class = TClass(GetWindowLong(Wnd,GWL_USERDATA));
Что здесь может быть непонятного? ]:->
-
Var
Engine: TEngine;
WndGlob: HWND;
. . . . .
WM_CREATE:
begin
Engine:= TEngien.Create;
Engine:= TEngine(GetWindowLong(WndGlob, GWL_USERDATA));
Result:= 0;
Exit;
end;
WM_LBUTTONDOWN:
begin
Engine.FTest:= True; Result:= 0;
end;
WM_RBUTTONDOWN:
begin
Engine.FTest:= False; Result:= 0;
end;
. . . . .
Engine.CreateWindow;
SetWindowLong(WndGlob, GWL_USERDATA, Longint(Engine));
-
> Б (23.07.09 19:57) [5]
Ахинея какая-то ..
-
> [5] Б (23.07.09 19:57) > Engine:= TEngien.Create; > Engine:= TEngine(GetWindowLong(WndGlob, GWL_USERDATA) > );
Это бред.
-
Engine:= TEngien.Create - это лишне.
Так как надо? Всё, как ты сказал.
-
WM_LBUTTONDOWN:
begin
Engine.FTest:= True; Result:= 0;
end;
WM_RBUTTONDOWN:
begin
Engine.FTest:= False; Result:= 0;
end; Engine не инициализирован. Естественно AV.
-
> Engine не инициализирован. Естественно AV.
Ну почему же? Инициализирован. С SetWindowLong, GetWindowLong - всё правильно?
Program Test;
. . . . .
Var
Engine: TEngine;
begin
Engine:= TEngine.Create;
. . . . .
Engine.Run;
End;
Procedure TEngine.Run;
begin
CreateWindow. . .; SetWindowLong(WndGlob, GWL_USERDATA, Longint(Engine));
Processing; Cleanup; End;
-
> [10] Б (23.07.09 21:26)
А код WndProc покажи целиком.
-
Function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
Case (Msg) of
WM_CREATE:
begin
Result:= 0;
Engine:= TEngine(GetWindowLong(WndGlob, GWL_USERDATA));
Exit;
end;
WM_DESTROY:
begin
PostQuitMessage(0);
Result:= 0;
end;
WM_LBUTTONDOWN:
begin
Engine.FTest:= True;
Result:= 0;
end;
WM_RBUTTONDOWN:
begin
Engine.FTest:= False;
Result:= 0;
end;
else
Result:= DefWindowProc(hWnd, Msg, wParam, lParam);
end;
End;
-
Ниче не понимаю... Короче как у меня сделано: void osal::cWnd::CreateWnd(int Width,int Height, bool Fullscreen, int PixelDepth, std::string Title)
;
LRESULT CALLBACK outsideWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
;
-
Сделал так:
Function TEngine.DoWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM;
lParam: LPARAM): LRESULT;
begin
Case Msg of
WM_DESTROY:
begin
PostQuitMessage(0); Result:= 0;
end;
WM_LBUTTONDOWN:
begin
FTest:= True; Result:= 0;
end;
WM_RBUTTONDOWN:
begin
FTest:= False; Result:= 0;
end;
else
Result:= DefWindowProc(hWnd, Msg, wParam, lParam);
end
End;
Function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
Result:= Engine.DoWndProc(hwnd, msg, wParam, lParam); End;
-
Function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
Result:= Engine.DoWndProc(hwnd, msg, wParam, lParam); End;
Это не то, о чем говорилось в первом сообщении. Это не классовая обертка. Engine может быть только один. И он к тому же глобальная переменная...
-
> Б (22.07.09 19:38) > Не хотелось бы пользоваться глобальными переменными, > а потом уже через них присваивать значения полям класса.
Вот такие глобальные переменные имелись ввиду. Конечно Engine - один, программист не участвует в его создании. Через Set/Get-WindowLong - от глобальных тоже не отвязатся.
-
> [16] Б (24.07.09 11:56) > Через Set/Get-WindowLong - от глобальных тоже не отвязатся.
Это еще почему??
-
P.S. Это не вопрос, а способ сказать что вы не правы. Собственно код в [13] работает без глобальных переменных в принципе.
|