2013-10-26 10 views
1

我剛學創建使用WINAPI一個GUI,但我遇到了一個問題。我可以創建這樣創建響應的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); 
    } 
} 

這比平常設置多一點,所以讓我解釋一下,爲了不燒CPU,您等待與WaitMessage的消息,它會阻止,直到事情發生,比如移動窗口,單擊,油漆等,如果有消息,所以稱它在一個while循環將確保它水渠消息quene的PeekMessage將返回true,如果返回0,GetMessage將獲取消息,這意味着您的應用程序稱爲PostQuitMessage(0)使得在消息循環中找到了一個WM_QUIT,這意味着是時候從消息循環中分離出來。其餘的翻譯和發送按照其名稱說。

最後,你需要自己的窗口過程:

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消息作出響應,以便關閉該窗口並將退出的消息發佈到您將捕獲並退出的消息循環中。

附加信息: 不需要釋放你的東西,因爲Windows爲你做了這樣的事情,所以它在下次啓動程序時不會被鎖定,但是至少在你的主循環後取消註冊你的窗口類是個好習慣。

順便說一句這是錯誤的主要功能:WinMain這是正確的。另外爲了避免更多的錯誤,請確保您編譯了一個Windows GUI應用程序。