2013-08-18 1 views
1

여러 창에 대한 프로그램을 쓰려고합니다. 이 프로그램에서 사용자가 한 창에서 왼쪽 버튼을 클릭하면 어떤 창을 클릭했는지에 대한 메시지가 표시됩니다. 여기 내 코드는 다음과 같습니다 난 그냥 window1- 실패 만들 말하는 코드를 실행하려고 할 때여러 창에 대한 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; 
} 

문제가!

+1

설명서가 말하는대로하고 CreateWindow가 실패하면 바로 뒤에 (다른 API 호출 전에) GetLastError를 호출하여 자세한 정보를 얻으십시오. – chris

+0

이것은 또한 최소한의 테스트 케이스를 줄이는 주요한 예입니다. 창 1이 작성되지 않습니다. 창 2와 3을 제거하면 코드가 2/3 즉시 사라져서 보며 실패했다고 가정합니다. – chris

답변

0

CreateWindow 함수는 핸들을 윈도우에 반환하거나 실패하면 NULL을 반환합니다. (ghFirstWnd == NULL)이 경우 "와"(ghFirstWnd == 0) "무슨 일이 일어나는지 확인 내가는 Win32를 사용하지 않기 때문에. 그럴거야.

경우에만이"window1- 만들 경우 그래서 '교체 실패한 "메시지가 표시되면"if (ghSecondWnd == 0) "을"if (ghSecondWnd == 1) "로 바꾸고 두 개의 메시지 상자가 나타나야합니다.

+0

메시지가 표시된 후에 프로그램이 종료됩니다. 그리고 nullptr이 null 포인터 (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; 
} 

, 그것은 당신의 실수를 발견하는 것이 훨씬 쉽게 귀하의 창 클래스 "first class"가이지만, CreateWindow 콜에서는 "MyWndClassName"이라는 클래스를 사용합니다. 클래스를 찾을 수 없으므로이를 사용하여 창을 만들 수 없습니다.

작은 오류 검사가 있습니다. 실제로 그것을 강조 할 한 가지는 GetLastError을 적절하게 사용하는 것입니다.

+0

괜찮 았어. "MyWndClassName"을 "first class" "second class"및 "third class"로 변경했습니다. – cniper

관련 문제