2013-08-18 130 views
1

我正在嘗試編寫多窗口程序。在這個程序中,當用戶在一個窗口上點擊時,它應該顯示哪個窗口被點擊。這裏是我的代碼:多窗口win32程序

#include<Windows.h> 
// Store handles to the main window and application instance globally. 
HWND ghFirstWnd =0; 
HWND ghSecondWnd=0; 
HWND ghThirdWnd=0; 
HINSTANCE ghAppInst=0; 
//======================================================================================== 
// WINDOW 1 
// Step 1: Define and implement the window procedure. 
LRESULT CALLBACK 
WndProc1(HWND hWnd,UINT msg,WPARAM wParam, LPARAM lParam) 
{ 
    switch(msg) 
    { 
    // Handle left mouse button click message. 
    case WM_LBUTTONDOWN: 
     MessageBox(0,L"first window ",L"MSG",MB_OK); 
     return 0; 
    // Handle key down message. 
    case WM_KEYDOWN: 
     if(wParam==VK_ESCAPE) 
      if(MessageBox(hWnd,L"sure ??",L"confirmation",MB_YESNO)==IDYES) 
       DestroyWindow(ghFirstWnd); 
     return 0; 
    // Handle destroy window message. 
    case WM_DESTROY: 
     PostQuitMessage(0); 
     return 0; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
//======================================================================================== 
// WINDOW 2 
//======================================================================================== 
LRESULT CALLBACK 
WndProc2(HWND hWnd,UINT msg, WPARAM wParam,LPARAM lParam) 
{ 
    switch(msg) 
    { 
    case WM_LBUTTONDOWN: 
     MessageBox(0,L"second window",L"msg",MB_OK); 
     return 0; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
//======================================================================================== 
// WINDOW 3 
//======================================================================================== 
LRESULT CALLBACK 
WndProc3(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
    switch(msg) 
    { 
    case WM_LBUTTONDOWN: 
     MessageBox(0,L"third window",L"msg",MB_OK); 
     return 0; 
    } 
    return DefWindowProc(hWnd,msg,wParam,lParam); 
} 
// WinMain: Entry point for windows application. 
int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR cmdLine,int showCmd) 
{ 
    // Save handle to application instance. 
    ghAppInst=hInstance; 
    // Step 2: Fill out a WNDCLASS instance. 
    WNDCLASS wc1; 
    wc1.style =CS_HREDRAW|CS_VREDRAW; 
    wc1.lpfnWndProc =WndProc1; 
    wc1.cbClsExtra=0; 
    wc1.cbWndExtra=0; 
    wc1.hInstance=ghAppInst; 
    wc1.hIcon=::LoadIcon(0,IDI_APPLICATION); 
    wc1.hCursor=::LoadCursor(0,IDC_ARROW); 
    wc1.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc1.lpszMenuName=0; 
    wc1.lpszClassName=L"first class"; 
    // Window 2 
    WNDCLASS wc2; 
    wc2.style=CS_HREDRAW|CS_VREDRAW; 
    wc2.lpfnWndProc=WndProc2; 
    wc2.cbClsExtra=0; 
    wc2.cbWndExtra=0; 
    wc2.hInstance=ghAppInst; 
    wc2.hIcon=::LoadIcon(0,IDI_APPLICATION); 
    wc2.hCursor=::LoadCursor(0,IDC_ARROW); 
    wc2.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc2.lpszMenuName=0; 
    wc2.lpszClassName=L"second class"; 
    // Window 3 
    WNDCLASS wc3; 
    wc3.style=CS_HREDRAW|CS_VREDRAW; 
    wc3.lpfnWndProc=WndProc3; 
    wc3.cbClsExtra=0; 
    wc3.cbWndExtra=0; 
    wc3.hInstance=ghAppInst; 
    wc3.hIcon=::LoadIcon(0,IDI_APPLICATION); 
    wc3.hCursor=::LoadCursor(0,IDC_ARROW); 
    wc3.hbrBackground=(HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc3.lpszMenuName=0; 
    wc3.lpszClassName=L"third class"; 
    // Step 3: Register with WNDCLASS instance with windows. 
    RegisterClass(&wc1); 
    RegisterClass(&wc2); 
    RegisterClass(&wc3); 
    // Step 4: Create the window, and save the handle in global window handle variable ghMainWnd. 
    ghFirstWnd=::CreateWindow(L"MyWndClassName",L"MyWindow1",WS_OVERLAPPEDWINDOW,0,0,50,50,0,0,ghAppInst,0); 
    ghSecondWnd=::CreateWindow(L"MyWndClassName",L"MyWindow2",WS_OVERLAPPEDWINDOW,50,0,50,50,0,0,ghAppInst,0); 
    ghThirdWnd=::CreateWindow(L"MyWndClassName",L"MyWindow3",WS_OVERLAPPEDWINDOW,100,0,50,50,0,0,ghAppInst,0); 
    if(ghFirstWnd==0) 
    { 
     ::MessageBox(0,L"create window1-failed",0,0); 
     return false; 
    } 
    if(ghSecondWnd==0) 
    { 
     ::MessageBox(0,L"create window2 failed",0,0); 
     return false; 
    } 
    if(ghThirdWnd==0) 
    { 
     ::MessageBox(0,L"create window3 failed",0,0); 
     return false; 
    } 
    // Step 5: Show and update the window. 
    ShowWindow(ghFirstWnd,showCmd); 
    UpdateWindow(ghFirstWnd); 
    ShowWindow(ghSecondWnd,showCmd); 
    UpdateWindow(ghSecondWnd); 
    ShowWindow(ghThirdWnd,showCmd); 
    UpdateWindow(ghThirdWnd); 
    // Step 6: Enter the message loop and don't quit until a WM_QUIT message is received. 
    MSG msg; 
    ZeroMemory(&msg,sizeof(MSG)); 
    while(GetMessage(&msg,0,0,0)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
    // Return exit code back to operating system. 
    return(int)msg.wParam; 
} 

問題是當我嘗試執行代碼它只是說創建window1-失敗!

+1

做文檔所說的話,如果'CreateWindow'失敗,在(在其他API調用之前)調用'GetLastError'來獲取更多信息。 – chris

+0

這也是減少到最小測試用例的最好例子。窗口1沒有被創建。擺脫Windows 2和3,假設它仍然失敗,你立即丟失2/3的代碼來查看。 – chris

回答

0

CreateWindow函數返回窗口句柄或失敗時返回NULL。 因此,用「if(ghFirstWnd == NULL)」代替'if(ghFirstWnd == 0)「並檢查會發生什麼,我不確定,因爲我沒有使用Win32

如果只有」create window1-失敗「的消息顯示可能試圖用」if(ghSecondWnd == 1)「代替」if(ghSecondWnd == 0)「,然後出現兩個消息框

+0

程序在顯示消息後退出。雖然'nullptr'是用於空指針的適當的東西(這與Win32無關),'if(!ghFirstWnd)'更好。無論如何,這並沒有改變任何東西。 NULL必須評估爲0,所以如果它編譯,我不知道如何改變它可以改變語義。 – chris

2

切斷程序,可以結束類似這樣的東西(我做了一些更改代碼本身,但它應該仍然工作在C++ 03):

#include <Windows.h> 

int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE, PSTR,int showCmd) 
{ 
    WNDCLASS wc1 = {}; 
    wc1.style = CS_HREDRAW|CS_VREDRAW; 
    wc1.lpfnWndProc = DefWindowProc; 
    wc1.hInstance = hInstance; 
    wc1.hIcon = ::LoadIcon(0,IDI_APPLICATION); 
    wc1.hCursor = ::LoadCursor(0,IDC_ARROW); 
    wc1.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); 
    wc1.lpszClassName = L"first class"; 

    RegisterClass(&wc1); 
    HWND ghFirstWnd = ::CreateWindow(L"MyWndClassName",L"MyWindow1",WS_OVERLAPPEDWINDOW,0,0,50,50,0,0,hInstance,0); 

    if(!ghFirstWnd) 
    { 
     ::MessageBox(0,L"create window1-failed",0,0); 
     return 1; 
    } 

    return 0; 
} 

這個小碼,它更容易發現你的錯誤你窗口類被稱爲「頭等」,但在您的CreateWindow調用中,您使用的類名爲「MyWndClassName」。無法找到該類,因此無法使用它創建窗口。

在旁註中,您幾乎沒有錯誤檢查。適當地使用GetLastError的一件事情會讓它變得更糟。

+0

行得通。將「MyWndClassName」更改爲「一等」「二等」和「三等」 – cniper