![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Почему программа создавая окно - вылетает? [D7, XP]
Б © (2009-11-21 12:09:00)Здрасти!
Создаю окно под рендер OpenGL след. самописной функцией.
Но если создать его в полноэкранном режиме (FFlag = True), то выскакивает "AV".
GetLastError пишет: "Не все окна, принадлежащие данному классу, закрыты (1412)".
В итоге в лог не попадает НЕ ОДНО сообщение.
Как быть?
Function TWindow.WndInit(Inst: HINST; x, y, W, H: integer; Title: PChar): boolean;
Var
Info: TWndClassEx;
Clss: PChar;
begin
Clss:= 'eXAAAXe';
ZeroMemory(@Info, SizeOf(Info));
With Info do
begin
cbSize := SizeOf(TWndClassEx);
Style := CS_OWNDC or CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS;
lpfnWndProc := @WndProc;
hInstance := Inst;
hIcon := LoadIcon(0, IDI_APPLICATION);
hCursor := LoadCursor(0, IDC_ARROW);
hbrBackground:= HBRUSH(GetStockObject(BLACK_BRUSH));
lpszClassName:= Clss;
hIconSm := LoadIcon(0, IDI_APPLICATION);
end;
If (RegisterClassEx(Info) = 0) then
begin
Log.Print('No register!'); (* Всё записываем в лог *)
Result:= False;
Exit;
end;
If FFull then (* Полноэкранный режим *)
begin
// Mode(640, 480, 16, 60); (* Меняем разрешение экрана *)
FWnd:= CreateWindowEx(WS_EX_APPWINDOW, Clss, Title, WS_POPUP or WS_CLIPCHILDREN or WS_CLIPSIBLINGS, x, y, W, H, 0, 0, Inst, nil);
Log.Print('FullScreen mode');
end else (* Оконный режим *)
begin
FWnd:= CreateWindowEx(WS_EX_APPWINDOW or WS_EX_WINDOWEDGE, Clss, Title, WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS, x, y, W, H, 0, 0, Inst, nil);
Log.Print('Windowed mode');
end;
SetWindowLong(FWnd, GWL_USERDATA, INTEGER(Self));
Log.Print('УРА!!!');
Result:= (FWnd <> 0);
End;
DVM (2009-11-21 14:01:00) [21]
> Б (21.11.09 13:52) [17]
Тогда даже не знаю что еще предположить, давай больше кода, но желательно минимально необходимый кусок.
Б (2009-11-21 13:52:00) [22]Результат не радует.
DVM (2009-11-21 13:43:00) [23]попробуй сделать глобальной переменной Info: TWndClassEx;
Б (2009-11-21 13:33:00) [24]Хм. У меня тоже работает.
Что-то я ничего не понимаю.
Мой пример без WS_POPUP работает.
DVM (2009-11-21 13:26:00) [25]вот набросал на скорую руку - ничего не вылетает
program winmin;
uses
windows, messages;
var
wc: TWndClassEx;
MainWnd: HWND;
Mesg: TMsg;
//------------------------------------------------------------------------------
function WindowProc(Wnd: HWND; Msg: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
case msg of
wm_destroy :
begin
PostQuitMessage(0);
Result := 0;
exit;
end;
else
Result := DefWindowProc(Wnd, Msg, wParam, lParam);
end;
end;
//------------------------------------------------------------------------------
var
xPos, yPos, nWidth, nHeight: integer;
const
Style = WS_POPUP;
ExtStyle =0;
begin
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WndClass1';
RegisterClassEx(wc);
xPos := 0;
yPos := 0;
nWidth := 1366;
nHeight := 768;
MainWnd := CreateWindowEx(ExtStyle, 'WndClass1', 'Caption', Style,
xPos, yPos, nWidth, nHeight, 0, 0, Hinstance, nil);
ShowWindow(MainWnd,CmdShow);
while GetMessage(Mesg,0,0,0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;
end.
Б (2009-11-21 13:19:00) [26]> попробуй вот такое сочетание стилей
Хм. Вылетает с теми же ошибками.
> ShowWindow(Wnd, SW_SHOWNORMAL);
> UpdateWindow(Wnd);
Этот код у меня находиться прямо перед циклом сообщений окна.
Чтобы при неудавшейся инициализации не лицезреть несколько секунд окно.
DVM (2009-11-21 13:10:00) [27]
> Б
еще обычно после создания окна делают
ShowWindow(Wnd, SW_SHOWNORMAL);
UpdateWindow(Wnd);
DVM (2009-11-21 13:09:00) [28]
> Б
попробуй вот такое сочетание стилей
Style = WS_POPUP or
WS_VISIBLE or WS_MAXIMIZE or
WS_CLIPSIBLINGS or
WS_CLIPCHILDREN or
WS_OVERLAPPED;
ExtStyle = WS_EX_LEFT or
WS_EX_RTLREADING or
WS_EX_TOOLWINDOW or
WS_EX_RIGHTSCROLLBAR;
Б (2009-11-21 12:58:00) [29]
> Ну и выкинь его, он же необязателен.
Нет. Без него не как.
В полноэкранном режиме окно должно быть без рамки. (OpenGL)
Хотя раньше с этим флагом проблем тоже не было.
DVM (2009-11-21 12:50:00) [30]
> Не-а, всё равно вылетает с флагом WS_POPUP, как никрути.
Странно. Мне кажется у меня раньше с этим стилем проблем не было. Ну и выкинь его, он же необязателен.
Б (2009-11-21 12:43:00) [31]
> Вот так должно заработать:
Не-а, всё равно вылетает с флагом WS_POPUP, как никрути.
> Тогда у тебя будут проблемы потом при обращении из этой процедуры к членам класса.
Я специально написал вот такую строчку:
SetWindowLong(FWnd, GWL_USERDATA, INTEGER(Self));
Чтобы спокой в WndProc работать с полями и методами своего класса.
DVM (2009-11-21 12:39:00) [32]
> Вот так должно заработать:
хотя у тебя тоже самое
DVM (2009-11-21 12:37:00) [33]
> Б (21.11.09 12:27) [5]
> Это, естесственно, не метод класса.
Ааа. Тогда у тебя будут проблемы потом при обращении из этой процедуры к членам класса. Ведь наверняка придется. Иначе зачем класс создавать. Советую продумать вопрос этот.
Вот так должно заработать:
if(fullscreen)
{
dwExStyle = WS_EX_APPWINDOW;
dwStyle = WS_POPUP;
ShowCursor(FALSE);
}
else
{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwStyle = WS_OVERLAPPEDWINDOW;
}
Б (2009-11-21 12:27:00) [34]> Может и нормально, но мне непонятно, эта WndProc - метод класса или > нет? Если метод класса то так неправильно делать.
Это, естесственно, не метод класса.
А обычная оконная процедура.
Function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
Б (2009-11-21 12:25:00) [35]И ещё.
Если убрать флаг WS_POPUP, то окно создаётся.
Не пойму в чём дело.
DVM (2009-11-21 12:25:00) [36]
> Б (21.11.09 12:21) [2]
> C калбэков всё нормально.
Может и нормально, но мне непонятно, эта WndProc - метод класса или нет? Если метод класса то так неправильно делать.
Б (2009-11-21 12:21:00) [37]
>
> > lpfnWndProc := @WndProc;
>
> вот тут ошибка
> <Цитата>
C калбэков всё нормально.
Если FFull поставить в False, то окно нормально создаёться и функционирует.
DVM (2009-11-21 12:11:00) [38]
> lpfnWndProc := @WndProc;
вот тут ошибка