2013-10-26 2 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로 자신의 클래스를 등록하고 처리하는 방법을 조사한 다음 동일한 클래스 이름을 사용하여 창을 만들어야합니다. 메시지를 처리하려면 고유 한 창 프로 시저가 있어야합니다. 시스템에 등록 된 모든 창 클래스는 자신의 기본 창 procudure를 실행하고 내가 아는 한 아무 것도 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; 
    } 

그런 다음 메인 루프 : 이것은 보통의 설치보다 조금 더, 그래서 나 CPU를 구울하기 위해, 설명 할 수

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가 도착 했으므로 메시지 루프에서 메시지 루프에서 벗어날 시간임을 알았습니다. 나머지 번역 및 발송은 이름이 말하는대로합니다. 따라서 당신은 여기를 처리 할 필요가 없습니다,

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를 지나온 모든 일반적으로 시스템에서 메시지를 발생 처리가 필수적이다 :

마지막으로 당신은 당신의 자신의 윈도우 프로 시저가 필요합니다. 창을 닫고 catch하고 종료 할 메시지 루프에 종료 메시지를 게시 할 때 보내지는 WM_CLOSE 메시지에 응답하면됩니다.

추가 정보 : 다음에 프로그램을 시작할 때 잠글 수 없으므로 물건을 놓을 필요는 없습니다.하지만 적어도 주 루프 이후에 창 클래스를 등록 취소하는 것이 좋습니다. .

Btw가 틀린 주 기능 : WinMain이 맞습니다. 또한 더 많은 버그를 피하기 위해 Windows GUI 응용 프로그램을 컴파일해야합니다.