如何創建一個win32程序

學過一段時間的c++,建立的都是win32 console application,我來介紹一下如何建立一個簡單的win32程序,相比win32 console application,會有大家常見的窗口,更像程序一些。

     首先要寫類似於main函數的WinMain,

int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)

       WINAPI是幹什麼的呢?它是調用聲明,相當於_stdcal。c++默認的調用聲明是_cdecl。兩者區別爲:

      _stdcal函數在結束後自己清棧,_cdecl由調用者(不是指人自己,指的是調用的程序)清棧。當函數參數個數可變的時候,只能_cdecl調用,在不知道個數的情況下,函數自己不知道怎麼清棧;不同的編譯器會按不同的方式堆棧,這樣會使得如果使用_cdecl聲明時,調用者不一定可以成功清棧。

(參考了http://blog.csdn.net/dengziliang001/article/details/17448789)

      hinstance是Windows爲應用程序產生的實例句柄,可以看成這個就是程序的地址,跟蹤程序。

      hprevinstance,現在已經不使用這個參數了。

      lpcmdline,與main中的命令行差不多,基本寫程序時不用管。

      ncmdshow,帶有如何打開主應用程序窗口的信息,比如最大化,最小化,一般用的多的是ShowWindow(),ncmd不怎麼用。

      函數體怎麼寫呢?看看下面:

      WNDCLASSEX winclass; // this will hold the class we create
       HWND   hwnd;// generic window handle
       MSG   msg;// generic message
       HDC        hdc;      // graphics device context


      // first fill in the window class stucture
      winclass.cbSize     = sizeof(WNDCLASSEX);
      winclass.style = CS_DBLCLKS | CS_OWNDC | 
                                             CS_HREDRAW | CS_VREDRAW;
    winclass.lpfnWndProc = WindowProc;
    winclass.cbClsExtra = 0;
    winclass.cbWndExtra = 0;
    winclass.hInstance = hinstance;
    winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    winclass.hCursor = LoadCursor(NULL, IDC_ARROW); 
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm             = LoadIcon(NULL, IDI_APPLICATION);

        WNDCLASSEX是一個類,因爲你要創建一個窗口,然後在上面輸入輸出操作,WNDCLSSEX可以看成一個窗口類,而winclass可以看成實例(即變量),hwnd,msg,hdc在後面會講到,首先要做的是填winclass的各個屬性,後面的一大串全是設置屬性,比較重要的是   winclass.style,它指出了窗口的重要屬性,如窗口寬度變化後會重畫,高度變化後會重畫,剩下的參數查msdn就知道了。

        然後你需要去註冊這個類,

        if (!RegisterClassEx(&winclass))
    return(0);

        外面的if,當沒註冊成功就返回0,防止程序沒註冊成功,往下運行出現未知的錯誤。

        然後就是創建一個窗口,

     if (!(hwnd = CreateWindowEx(NULL,                  // extended style
                            WINDOW_CLASS_NAME,     // class
   "Demo", // title
   WS_OVERLAPPEDWINDOW | WS_VISIBLE,
   0,0, // initial x,y
   500,400,  // initial width, height
   NULL,   // handle to parent 
   NULL,   // handle to menu
   hinstance,// instance of this application
   NULL)))  // extra creation parms
     return(0);

         CreateWindowEx()會返回一個指向窗口的的句柄,相當於它的地址。

         上面的一系列都可以直接複製張貼,根據需要,改一改屬性即可,然後我一般會編一個循環,去處理消息。

    while(TRUE)
{
    
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  { 
   TranslateMessage(&msg);
            DispatchMessage(&msg);
  } // end if
    } // end while
return(msg.wParam);
}
其中 if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
   { 
   TranslateMessage(&msg);
            DispatchMessage(&msg);
   } 

         理解成先判斷有沒有消息,有的話就傳遞給相應的程序處理,消息可以使單擊鼠標左鍵,關閉窗口等。

之後return,就寫好主函數。

         除了主函數還需要寫一個消息處理函數,每個窗口都有一個窗口處理函數,而關聯兩者,就是在設置窗口屬性時的winclass.lpfnWndProc= WindowProc,WindowProc是處理函數的名字,當窗口有相應的消息的時候,就會調用處理函數處理.下面是一個窗口處理函數:

         LRESULT CALLBACK WindowProc(HWND hwnd, 
                          UINT msg, 
                                                                         WPARAM wparam, 
                                                                         LPARAM lparam)
{

PAINTSTRUCT ps;

switch(msg){

case WM_CREATE: 

        {
        } break;
     case WM_PAINT: 
{
        BeginPaint(hwnd,&ps); 
            EndPaint(hwnd,&ps);
               return(0);
    } break;
     case WM_DESTROY: 
{
     PostQuitMessage(0);

     return(0);
} break;
  default:break;

return (DefWindowProc(hwnd, msg, wparam, lparam));

首先看一下函數的參數,hwnd 是調用窗口的句柄,便於對窗口操作,msg有消息類型的信息,wparam,lparam包含具體消息的細節。


總之其實上面的都可以直接複製張貼,至於該怎麼操作只需要改一下處理函數,還有在while循環裏做些填充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章