2013-10-26 4 views
1

Я просто учился создавать gui с помощью winapi, но у меня возникла проблема. Я могу создать окно, как этотСоздание ответного Windows winapi C++

#include "stdafx.h" 
#include <windows.h> 

int main() 
{ 
    HWND hwnd = CreateWindow(L"STATIC",NULL,WS_VISIBLE|WS_SYSMENU|WS_CAPTION,0,0,600,600,NULL,NULL,NULL,NULL); 
    UpdateWindow(hwnd); 
    MSG msg; 

    while(GetMessage(&msg, NULL, 0, 0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    _gettch(); 
} 

Но окна не будет закрываться, когда нажать на кнопку закрытия, и окно не может быть перетаскивать или перемещать. Мне было интересно, как я включу эти функции окна.

ответ

1

Статических окон нет для обычных окон, вы должны попробовать и посмотреть, как зарегистрироваться и обработать свой собственный класс с помощью RegisterWindowEx, а затем использовать одно и то же имя класса для создания окна. Для обработки сообщений необходимо иметь собственную процедуру окна. Все классы окон, зарегистрированные в системе, запускают собственное пронуклевое окно по умолчанию, и насколько я знаю, ни один из них не обрабатывает WM_CLOSE (это кнопка закрытия), поэтому вы не можете ее закрыть.

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

Как настроить:

WNDCLASSEX wndcls; 
HWND hMainWnd; 

// Register your own window class 
    ZeroMemory(&wndcls,sizeof(WNDCLASSEX)); 
    wndcls.cbSize=sizeof(WNDCLASSEX); 
    wndcls.style=CS_VREDRAW+CS_HREDRAW; 
    wndcls.lpfnWndProc=&appWndFunc; 
    wndcls.hInstance=hInstance; 
    wndcls.hIcon=hMainIcon;  // or just LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MAIN_ICON)) 
    wndcls.hIconSm=hMainIcon; 
    wndcls.hCursor=LoadCursor((HINSTANCE)NULL,IDC_ARROW); 
    wndcls.hbrBackground=(HBRUSH)COLOR_APPWORKSPACE; 
    wndcls.lpszClassName="myWndClass"; 
    if (RegisterClassEx(&wndcls)==0) 
    { 
     // failed to register class name 
     return false; 
    } 

// Create window with your own class 
    hMainWnd=CreateWindowEx(0,\ 
          "myWndClass","widnow title",\ 
          WS_OVERLAPPEDWINDOW|WS_VISIBLE,\ 
          0,\ 
          0,\ 
          250,\ 
          250,\ 
          hMainWnd,NULL,hInstance,NULL); 

    if (hMainWnd==(HWND)NULL) 
    { 
     // failed to create main window 
     return false; 
    } 

Тогда ваш главный цикл:

bool bAppMainLoop=false 
while(!bAppMainLoop) 
{ 
    WaitMessage(); 
    while(PeekMessage(&emsg,NULL,0,0,PM_NOREMOVE)) 
    { 
     if(GetMessage(&emsg,NULL,0,0)==0) 
     { 
      bAppMainLoop=true; 
      break; 
     } 
     TranslateMessage(&emsg); 
     DispatchMessage(&emsg); 
    } 
} 

Это немного больше, чем обычно установки, поэтому позвольте мне объяснить, чтобы не сгореть процессор, вы ждете сообщения с WaitMessage, оно будет блокироваться до тех пор, пока что-то не произойдет, например, переместите окно, нажмите, нарисуйте и т. д. PeekMessage вернет true, если есть сообщение, вызывающее его в цикле while, убедитесь, что оно истощает сообщение quene, GetMessage получит сообщение, если оно вернет 0, это означает, что ваше приложение называется PostQuitMessage (0), так что WM_QUIT был найден в контуре сообщения, что означает, что пришло время вырваться из цикла сообщений. Остальное Translate and Dispatch делает то, что он говорит.

Наконец вам нужна собственная оконная процедура:

LRESULT CALLBACK appWndFunc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 
{ 
    if (uMsg==WM_CLOSE) 
    { 
     PostQuitMessage(0); 
     return 0; 
    } 
    return DefWindowProc(hWnd,uMsg,wParam,lParam); 
} 

DefWindowProc является существенным, который обрабатывает все общераспространенных сообщения из системы, таким образом, вам не нужно обрабатывать их здесь. Вы просто отвечаете на сообщение WM_CLOSE, которое отправляется, когда вы хотите закрыть окно, и отправить сообщение о выходе в цикл сообщения, который вы поймаете и выйдете.

Дополнительная информация: Не требуется освобождать ваш материал, так как окна делают это для вас, поэтому он не будет заблокирован при следующем запуске вашей программы, но это хорошая практика, по крайней мере, отменить регистрацию вашего класса окон после основного цикла ,

Btw это неправильная основная функция: WinMain, что является правильным. Кроме того, чтобы избежать еще большего количества ошибок, убедитесь, что вы скомпилируете приложение Windows GUI.

Смежные вопросы