2013-05-26 86 views
1

我想在一個500×500窗口中創建一個按鈕,問題是,按鈕不會出現在Windows,並單擊單獨窗口觸發按鈕的程序/處理器:win32的按鈕不showimg

#include <windows.h> 

LRESULT CALLBACK MainWindowHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam); 
LRESULT CALLBACK ButtonHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam); 

LPCSTR FrameClassName = "MainWindow"; 
LPCSTR ButtonClassName = "Button"; 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) 
{ 
WNDCLASSEX Frame; 
HWND FrameHandle; 
WNDCLASSEX Button; 
HWND ButtonHandle; 

MSG Msg; 

Frame.cbSize  = sizeof(WNDCLASSEX); 
    Frame.style   = 0; 
    Frame.lpfnWndProc = MainWindowHandler; 
    Frame.cbClsExtra = 0; 
    Frame.cbWndExtra = 0; 
Frame.hInstance  = hInstance; 
Frame.hIcon   = LoadIcon(NULL, IDI_APPLICATION); 
Frame.hCursor  = LoadCursor(NULL, IDC_ARROW); 
Frame.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
Frame.lpszMenuName = NULL; 
Frame.lpszClassName = FrameClassName; 
    Frame.hIconSm  = LoadIcon(NULL, IDI_APPLICATION); 

Button.cbSize  = sizeof(WNDCLASSEX); 
    Button.style   = 0; 
    Button.lpfnWndProc = ButtonHandler; 
    Button.cbClsExtra = 0; 
    Button.cbWndExtra = 0; 
Button.hInstance  = hInstance; 
Button.hIcon   = LoadIcon(NULL, IDI_APPLICATION); 
Button.hCursor  = LoadCursor(NULL, IDC_ARROW); 
Button.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
Button.lpszMenuName = FrameClassName; 
Button.lpszClassName = ButtonClassName; 
    Button.hIconSm  = LoadIcon(NULL, IDI_APPLICATION); 

if(!RegisterClassEx(&Frame)) 
{ 
    MessageBox(NULL,"Registration Failure","ERROR",MB_ICONWARNING|    MB_OK); 
    return 0; 
} 
if(!RegisterClassEx(&Button)) 
{ 
    MessageBox(NULL,"Registration Failure","ERROR",MB_ICONWARNING|    MB_OK); 
    return 0; 
} 

FrameHandle = CreateWindowEx(WS_EX_CLIENTEDGE, 
        FrameClassName, 
        "Application", 
        WS_OVERLAPPEDWINDOW, 
        CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, 
        NULL, NULL, hInstance, NULL); 

ButtonHandle = CreateWindowEx(0, ButtonClassName, "My Button", 
    WS_CHILD | WS_VISIBLE, 250, 250, 30, 20, FrameHandle, 
    (HMENU)FrameHandle, hInstance, NULL); 

SendDlgItemMessage(ButtonHandle, 12, WM_SETFONT, 
    (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0)); 


ShowWindow(FrameHandle, nCmdShow); 
UpdateWindow(FrameHandle); 
ShowWindow(ButtonHandle, nCmdShow); 
UpdateWindow(ButtonHandle); 

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

} 

LRESULT CALLBACK MainWindowHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
switch(msg) 
{ 
case WM_LBUTTONDOWN: 
    MessageBox(obj,"CLICKED!","BUTTON",0); 
    break; 
    case WM_CLOSE: 
    DestroyWindow(obj); 
     break; 
    case WM_DESTROY: 
    PostQuitMessage(0); 
     break; 
    default: 
     return DefWindowProc(obj, msg, wParam, lParam); 
} 
return 0; 
} 

LRESULT CALLBACK ButtonHandler(HWND obj, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
switch(msg) 
{ 
    case WM_CLOSE: 
    DestroyWindow(obj); 
     break; 
    case WM_DESTROY: 
    PostQuitMessage(0); 
     break; 
    default: 
     return DefWindowProc(obj, msg, wParam, lParam); 
} 
return 0; 
} 

我錯過了什麼?

回答

4

這不是你如何創建一個按鈕。

按鈕控件使用由公共控件庫預先定義的特殊窗口類。您不需要註冊窗口類,它已經註冊。關於使用通用控件的推薦閱讀是here on MSDN

您只需要撥打電話CreateWindow,只需確保使用正確的類名:WC_BUTTON(由公共控件頭文件定義爲"BUTTON")。

對於控件,你也一般要包括WS_TABSTOP風格,和一個按鈕具體而言,您需要包括button styles -e.g.之一,BS_DEFPUSHBUTTONBS_PUSHBUTTON

最後,當您撥打CreateWindow時,您傳遞的參數hMenu的值錯誤。對於子窗口(如控件),這是控件的唯一標識符,而不是其父窗口的句柄。如果它是第一個控件,則可以給它一個ID爲1。最好在代碼中使用常量,以便以後可以通過編程方式與控件進行交互。

#include <CommCtrl.h> // somewhere at the top of your code file 

ButtonHandle = CreateWindowEx(0, 
           WC_BUTTON, 
           "My Button", 
           WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON, 
           250, 250, 30, 20, 
           FrameHandle, 
           (HMENU)1, // or some other unique ID for this ctrl 
           hInstance, 
           NULL); 

既然你已經包括了WS_VISIBLE風格,你並不需要此代碼(你可能不應該使用nCmdShow與子窗口反正):

// unnecessary code: 
ShowWindow(ButtonHandle, nCmdShow); 
UpdateWindow(ButtonHandle); 

最後,我可以沒有幫助,但注意到你正在使用ANSI字符串文字。今天所有的Windows應用程序都應該使用Unicode支持來構建,這需要您使用寬字符串文字。爲了得到這些,在每個前綴前加上L並使用LPCWSTR類型:LPCWSTR FrameClassName = L"MainWindow";不這樣做應該已經生成編譯器錯誤;新項目的默認設置定義了UNICODE預處理器符號。如果你的項目沒有完成,你現在應該做。

+0

我是初學者,我會嘗試使用您的解決方案。謝謝 –

+1

@Maurice一個好的教程可能會有用。通過反覆試驗學習Win32 API編程相當困難!最好的資源是Charles Petzold的經典着作,[Programming Windows,5th edition](http://www.amazon.com/Programming-Windows%C2%AE-Edition-Microsoft-Series/dp/157231995X)。但如果失敗了,[這個在線教程](http://www.winprog.org/tutorial/start.html)並不是一件壞事。 –