丰满人妻一区二区三区无码AV|国产乱色国产精品免费视频|国产精品一区二区不卡的视频|2020精品国产福利在线观看香蕉

    1. <rp id="2o2at"><nav id="2o2at"></nav></rp>
      
      

      <rt id="2o2at"></rt>
      <ruby id="2o2at"><nav id="2o2at"></nav></ruby>

    2. <rp id="2o2at"><meter id="2o2at"></meter></rp>

        <tt id="2o2at"><form id="2o2at"></form></tt>

      1. <source id="2o2at"></source>

          首頁 > 編程 > Java > 正文

          WinAPI簡單入門

          2019-09-06 23:33:14
          字體:
          來源:轉載
          供稿:網友

                              不要覺得奇怪,雖然我們擁有眾多“所見即所得”的編程方式來開發眾多界面精美的應
          用程序,這些可視化的編程環境提供了大量的類庫和控件,但是在開發者享受方便的同時,
          他們的手腳已經不知不覺的受到了限制,有很多深入到Windows內部的操作它們無法完成,
          為什么?因為所用的類庫不支持。

            事實上這些類庫與控件都是架構在Window API的基礎上面的,API即 Application
          Programming Interface -- 應用編程接口 的縮寫,它不僅為應用程序所調用,同時也是
          Windows的一部分,Windows自身的運行也調用這些API函數。要了解如何使用API就必須了
          解一些Windows的運行機制。

            簡單地說,Windows是由事件驅動的搶占式多任務操作系統。事件驅動是相對于過程驅
          動而言的,它改變了原來文件的順序執行方式;Windows既然是多任務系統,就必須能同時
          處理多個事件,系統為應用程序生成一個消息隊列,消息在上面被張貼和發送,應用程序只
          要從其消息隊列中取出消息,然后一一執行就可以了。

            現在,我將使用最最基本的范例程序 HelloWin 來說明WIN32 API的運行機制

          首先,一個程序一定要有進入點,Win32 App的進入點函數的名稱是WinMain,它的原型如下
          int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
          LPSTR lpCmdLine,int nCmdShow)


          hInstance是所謂的“實例句柄”,它是一個數值,當程序在Windows下運行的時候,它被用
          來唯一的標示這個程序,雖然用戶可能同時運行多個同一個程序,即運行多個“實例”,我
          們可以看到,每一個實例都有不同的hInstance值。

          hPrevInstance,簡單地說就是沒用…它是存在于16位Windows程序中的,在編寫
          Windows 9x/NT/2000 程序的時候,總應該是NULL。

          szCmdLine是一個指針,指向一個以0為終結的字串,里面包含傳給該程序的命令行參數,
          如果想要讓程序處理命令行,那么這個參數就有用了。

          iCmdShow參數是一個數值,指示窗口將如何被顯示,這個數值由在Windows下運行該程序的
          程序所決定,通常是SW_SHOWNORMAL。

          接下來是注冊一個窗口類,窗口總是從窗口類的基礎上創建的,窗口類用以標示處理窗口消
          息的窗口過程,注冊窗口類時使用 RegisterClassEx() 函數,它只需要一個參數,一個指向
          類型為 WNDCLASSEX 的結構指針。

          具體注冊初始是這樣的:
          WNDCLASSEX wcex;

          wcex.cbSize = sizeof(WNDCLASSEX);     //結構的大小

          wcex.style = CS_HREDRAW | CS_VREDRAW; //類風格
          wcex.lpfnWndProc = (WNDPROC)WndProc;  //窗口類的窗口過程
          wcex.cbClsExtra = 0;            //在類結構中預留的空間
          wcex.cbWndExtra = 0;           //在Windows內部保存的窗口結構中預留的空間
          wcex.hInstance = hInstance;        //程序的實例句柄
          wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_EXAMPLE);  //程序圖標
          wcex.hCursor = LoadCursor(NULL, IDC_ARROW);         //結構的大小
          wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);    //指定窗口的背景顏色
          wcex.lpszMenuName = (LPCSTR)IDC_EXAMPLE;         //菜單
          wcex.lpszClassName = szWindowClass;             //類名,和程序名相同
          wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);    //也是程序圖標

          return RegisterClassEx(&wcex);

          接下來,定義一個HWND,然后使用 CreateWindow() 函數,原型如下:
          HWND CreateWindow(
            LPCTSTR lpClassName,    // 窗口類名
            LPCTSTR lpWindowName,  // 窗口標題
            DWORD dwStyle,       // 窗口風格
            int x,             // 初始x
            int y,             // 初始y
            int nWidth,          // 窗口寬
            int nHeight,         // 窗口高
            HWND hWndParent,     // 父窗口句柄
            HMENU hMenu,       // 菜單句柄
            HINSTANCE hInstance,   // 實例句柄
            LPVOID lpParam       // 創建參數
          );

          在 CreateWindow() 調用返回之后,Windows內部已經創建了這窗口。但是窗口并為顯示,
          還需要兩個調用,一個是 ShowWindow(hwnd, iCmdShow):第一個參數是剛剛創建的窗口
          句柄,第二個參數是傳遞給WinMain的nCmdShow;另一個是 UpdateWindow(hwnd) ,導致
          客戶區域被繪制。

          接下來,程序通過執行一塊被稱為“消息循環”的代碼從消息隊列中取出消息

          while (GetMessage(&msg, NULL, 0, 0))
          {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
              TranslateMessage(&msg);
              DispatchMessage(&msg);
            }
          }

          消息循環以 GetMessage 開始,它從消息隊列中取出一條消息,只要從消息隊列中取出消
          息的 Message 域不為 WM_QUIT,GetMessage 就返回一個非零值,否則將導致程序退出
          消息循環,然后程序中止,返回 msg 結構的 wParam 參數。在循環中,TranslateMessage
          將 msg 結構的內容進行修改,而 DispatchMessage 找出準備調用的窗口過程。

          上面進行的僅僅是準備性工作:注冊窗口類、創建窗口、顯示窗口、進入消息循環取出消息
          而實際的動作都發生在窗口過程中。

          LRESULT CALLBACK WndProc(HWND hWnd, //剛剛創建的窗口句柄
            UINT message,           //得到的消息
            WPARAM wParam,
            LPARAM lParam           //消息的進一步詳細的參數
          )

          在程序中窗口過程通常是命名為 WndProc 的函數,其實窗口過程可以任意的命名,一個
          Windows程序可以包含多個窗口過程,一個窗口過程總是與調用了 RegisterClassEx 注冊的
          窗口類相關聯,CreateWindow 函數根據窗口類來創建窗口,但是一個窗口類可以被用來創
          建多個窗口。


          消息收到之后,接下來應該根據消息的不同來進行處理
          switch(message)
          {
           case …:
           …
           …

          HelloWin程序只需要處理兩條消息,即 WM_PAINT 和 WM_DESTROY。

          WM_PAINT 消息在Windows程序中的地位極其重要,當窗口客戶區的一部分或者全部變為
          “無效”,必須進行刷新的時候,將由這條消息通知程序。

          為什么客戶區域會變得無效呢?在創建窗口的時候,整個客戶區都是無效的,因為還沒有畫
          任何的東西。第一條 WM_PAINT 消息指示窗口過程在窗口上面畫一些東西;還有在用戶改
          變了窗口的大小之后,客戶區域重新變得無效,除此之外最小化窗口之后再還原、窗口的一
          部分被覆蓋,都會引發這條消息。

          WM_DESTROY消息則是當用戶按下“關閉”按鈕的時候被觸發,標準的處理方法是調用
          PostQuitMessage 將一條 WM_QUIT 消息插入消息隊列,這將使得 GetMessage 函數調用
          返回0,從而退出消息循環,結束整個程序。

          其實,從上面可以看出,Windows程序的這種運行機制并不是很難理解,真正困難的是不知
          道調用什么函數去完成想要的操作,以及怎樣調用那些函數,從而靈活的進行底層API程序
          開發,這是一個循序漸進的積累過程,沒有捷徑可走的。請各位一定要記住。
          發表評論 共有條評論
          用戶名: 密碼:
          驗證碼: 匿名發表

          圖片精選

          1. <rp id="2o2at"><nav id="2o2at"></nav></rp>
            
            

            <rt id="2o2at"></rt>
            <ruby id="2o2at"><nav id="2o2at"></nav></ruby>

          2. <rp id="2o2at"><meter id="2o2at"></meter></rp>

              <tt id="2o2at"><form id="2o2at"></form></tt>

            1. <source id="2o2at"></source>