Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему программа создавая окно - вылетает? [D7, XP]


Страницы:   1 2

Б ©   (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;

вот тут ошибка


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо