• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            思勤無邪

            上學時,因我年齡最小,個頭也最小,上課時,就像大猩猩堆里的猴一般。如今,這猴偶爾也把最近的一些情況寫在這里。

               :: 首頁 :: 聯系 :: 聚合  :: 管理
              132 Posts :: 1 Stories :: 178 Comments :: 0 Trackbacks

            公告

                 吾日常三省吾身,曰思、曰勤、曰無邪。

            積分與排名

            • 積分 - 183658
            • 排名 - 141

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜


                閑時順手翻了翻《Windows Graphics Programming》,發現里面的示例代碼很不錯,對設計應用程序框架和理解現有的應用程序框架很有幫助(尤其是MFC)。先來看一個很簡單的用面向對象的思想包裝API函數的KWindow類。示例代碼貼出來,申明一下,代碼不是我寫的,但有可能做一些改動,加了很多羅嗦的注釋,只是想節約以后閱讀的時間。

                下載示例project

                KWindow類需要完成注冊窗口、創建窗口、處理窗口消息等用API編寫程序時要處理的任務。由于每個窗口類對不同的消息會有不同的處理,所以首先想到了消息處理函數采用虛函數來實現(這種方式缺點是消息太多會使虛函數表過大,MFC采用消息映射,這里只是為了簡單),因為虛函數肯定是成員函數,有this指針,Win32 API不能把一個虛函數作為窗口消息處理函數。通常的解決辦法是采用靜態函數,在這個靜態函數里在想辦法產生一個指向代表當前窗口的KWindow實例的指針來調用對應窗口的消息處理函數。
            // win.h
            #pragma once
            // 以K開頭來命名類,是希望與MFC有明顯區別
            class KWindow
            {
            protected:
                
            // 處理WM_PAINT消息,由WndProc調用
                virtual void OnDraw(HDC hDC)
                
            {
                }

                
            // 處理WM_KEYDOWN消息,由WndProc調用
                virtual void OnKeyDown(WPARAM wParam, LPARAM lParam)
                
            {
                }

                
            // 真正的消息分發/處理函數
                virtual LRESULT WndProc(HWND hWnd, UINT uMsg,
                    WPARAM wParam, LPARAM lParam);
                
            // API中注冊的消息處理函數,不能是成員函數,因為成員函數有this指針
                static LRESULT CALLBACK WindowProc(HWND hWnd,
                    UINT uMsg, WPARAM wParam, LPARAM lParam);
                
            // 派生類可以在這里修改窗口的屬性,如圖標、菜單等
                virtual void GetWndClassEx(WNDCLASSEX & wc);
            public:
                
            // 保存該窗口對應的HWND
                HWND  m_hWnd;
                
            // m_hWnd 由CreateEx成員函數調用API函數CreateWindowEx賦值
                KWindow(void)
                
            {
                    m_hWnd 
            = NULL;
                }

                
            // destructor
                virtual ~KWindow(void)
                
            {
                }

                
            // 調用API函數CreateWindowEx創建窗口
                virtual bool CreateEx(DWORD dwExStyle,
                    LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
                    
            int x, int y, int nWidth, int nHeight, HWND hParent,
                    HMENU hMenu, HINSTANCE hInst);
                
            // 注冊窗口
                bool RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst);
                
            // 消息循環
                virtual WPARAM MessageLoop(void);

                BOOL ShowWindow(
            int nCmdShow) const
                
            {
                    
            return ::ShowWindow(m_hWnd, nCmdShow);
                }


                BOOL UpdateWindow(
            voidconst
                
            {
                    
            return ::UpdateWindow(m_hWnd);
                }

            }
            ;

            // win.cpp
            #define STRICT
            #define WIN32_LEAN_AND_MEAN

            #include 
            <windows.h>
            #include 
            <assert.h>
            #include 
            <tchar.h>
            #include 
            ".\win.h"

            // 真正的消息分發/處理函數
            LRESULT KWindow::WndProc(HWND hWnd, UINT uMsg,
                                     WPARAM wParam, LPARAM lParam)
            {
                
            switch( uMsg )
                
            {
                
            case WM_KEYDOWN:
                    OnKeyDown(wParam, lParam);
                    
            return 0;
                
            case WM_PAINT:
                    
            {
                        PAINTSTRUCT ps;

                        BeginPaint(m_hWnd, 
            &ps);
                        OnDraw(ps.hdc);
                        EndPaint(m_hWnd, 
            &ps);
                    }

                    
            return 0;
                
            case WM_DESTROY:
                    PostQuitMessage(
            0);
                    
            return 0;
                }


                
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
            }


            // API中注冊的消息處理函數,將操作系統的消息分發到正確的KWindow對象
            LRESULT CALLBACK KWindow::WindowProc(HWND hWnd, UINT uMsg,
                                                 WPARAM wParam, LPARAM lParam)
            {
                KWindow 
            * pWindow;

                
            if ( uMsg == WM_NCCREATE )    // 窗口創建時收到的第一個消息
                {
                    
            // 通過lParam找出該窗口對應的KWindow指針,并調用
                    
            // SetWindowLong(GWL_USERDATA)保存
                    assert( ! IsBadReadPtr((void *) lParam,
                        
            sizeof(CREATESTRUCT)) );
                    MDICREATESTRUCT 
            * pMDIC = (MDICREATESTRUCT *)
                        ((LPCREATESTRUCT) lParam)
            ->lpCreateParams;
                    pWindow 
            = (KWindow *) (pMDIC->lParam);

                    assert( 
            ! IsBadReadPtr(pWindow, sizeof(KWindow)) );
                    SetWindowLong(hWnd, GWL_USERDATA, (LONG) pWindow);
                }

                
            else
                
            {
                    
            // 調用GetWindowLong(GWL_USERDATA)找回在WM_NCCREATE消息中保存的
                    
            // KWindow指針
                    pWindow=(KWindow *)GetWindowLong(hWnd, GWL_USERDATA);
                }


                
            if ( pWindow )
                
            {
                    
            return pWindow->WndProc(hWnd, uMsg, wParam, lParam);
                }

                
            else
                
            {
                    
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
                }

            }


            bool KWindow::RegisterClass(LPCTSTR lpszClass, HINSTANCE hInst)
            {
                WNDCLASSEX wc;

                
            if ( ! GetClassInfoEx(hInst, lpszClass, &wc) )
                
            {
                    GetWndClassEx(wc);

                    wc.hInstance     
            = hInst;
                    wc.lpszClassName 
            = lpszClass;
                    
            if ( !RegisterClassEx(&wc) )
                        
            return false;
                }


                
            return true;
            }


            bool KWindow::CreateEx(DWORD dwExStyle,
                                   LPCTSTR lpszClass, LPCTSTR lpszName, DWORD dwStyle,
                                   
            int x, int y, int nWidth, int nHeight, HWND hParent,
                                   HMENU hMenu, HINSTANCE hInst)
            {
                
            if ( ! RegisterClass(lpszClass, hInst) )
                    
            return false;

                
            // use MDICREATESTRUCT to pass this pointer, support MDI child window
                MDICREATESTRUCT mdic;
                memset(
            & mdic, 0sizeof(mdic));
                mdic.lParam 
            = (LPARAM) this;
                m_hWnd 
            = CreateWindowEx(dwExStyle, lpszClass, lpszName,
                    dwStyle, x, y, nWidth, nHeight,
                    hParent, hMenu, hInst, 
            & mdic);

                
            return m_hWnd != NULL;
            }


            // 派生類中可以改寫默認屬性
            void KWindow::GetWndClassEx(WNDCLASSEX & wc)
            {
                memset(
            & wc, 0sizeof(wc));

                wc.cbSize        
            = sizeof(WNDCLASSEX);
                wc.style         
            = 0;
                wc.lpfnWndProc   
            = WindowProc;
                wc.cbClsExtra    
            = 0;
                wc.cbWndExtra    
            = 0;
                wc.hInstance     
            = NULL;
                wc.hIcon         
            = NULL;
                wc.hCursor       
            = LoadCursor(NULL, IDC_ARROW);
                wc.hbrBackground 
            = (HBRUSH)GetStockObject(WHITE_BRUSH);
                wc.lpszMenuName  
            = NULL;
                wc.lpszClassName 
            = NULL;
                wc.hIconSm       
            = NULL;
            }


            // Message Loop
            WPARAM KWindow::MessageLoop(void)
            {
                MSG msg;

                
            while ( GetMessage(&msg, NULL, 00) )
                
            {
                    TranslateMessage(
            &msg);
                    DispatchMessage(
            &msg);
                }


                
            return msg.wParam;
            }


            // Hello.cpp
            #define STRICT
            #define WIN32_LEAN_AND_MEAN

            #include 
            <windows.h>
            #include 
            <assert.h>
            #include 
            <tchar.h>

            #include 
            "win.h"

            const TCHAR szMessage[] = _T("Hello, World !");
            const TCHAR szFace[]    = _T("Times New Roman");
            const TCHAR szHint[]    = _T("Press ESC to quit.");
            const TCHAR szProgram[] = _T("HelloWorld3");

            // copy CenterText from Hello2.cpp

            class KHelloWindow : public KWindow
            {
                
            void CenterText(HDC hDC, int x, int y, LPCTSTR szFace,
                    LPCTSTR szMessage, 
            int point)
                
            {
                    HFONT hFont 
            = CreateFont(
                        point 
            * GetDeviceCaps(hDC, LOGPIXELSY) / 72,
                        
            000, FW_BOLD, TRUE, FALSE, FALSE,
                        ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
                        PROOF_QUALITY, VARIABLE_PITCH, szFace);
                    assert(hFont);

                    HGDIOBJ hOld 
            = SelectObject(hDC, hFont);

                    SetTextAlign(hDC, TA_CENTER 
            | TA_BASELINE);

                    SetBkMode(hDC, TRANSPARENT);
                    SetTextColor(hDC, RGB(
            000xFF));
                    TextOut(hDC, x, y, szMessage, _tcslen(szMessage));
                    SelectObject(hDC, hOld);
                    DeleteObject(hFont);
                }


                
            void OnKeyDown(WPARAM wParam, LPARAM lParam)
                
            {
                    
            if (wParam==VK_ESCAPE )
                    
            {
                        PostMessage(m_hWnd, WM_CLOSE, 
            00);
                    }

                }


                
            void OnDraw(HDC hDC)
                
            {
                    TextOut(hDC, 
            00, szHint, lstrlen(szHint));
                    CenterText(hDC, GetDeviceCaps(hDC, HORZRES)
            /2,
                        GetDeviceCaps(hDC, VERTRES)
            /2,
                        szFace, szMessage, 
            72);
                }


                
            // 修改默認窗口屬性
                void GetWndClassEx(WNDCLASSEX & wc)
                
            {
                    memset(
            & wc, 0sizeof(wc));

                    wc.cbSize        
            = sizeof(WNDCLASSEX);
                    wc.style         
            = 0;
                    wc.lpfnWndProc   
            = WindowProc;
                    wc.cbClsExtra    
            = 0;
                    wc.cbWndExtra    
            = 0;
                    wc.hInstance     
            = NULL;
                    wc.hIcon         
            = NULL;
                    wc.hCursor       
            = LoadCursor(NULL, IDC_ARROW);
                    
            // 將背景畫刷改為透明
                    wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
                    wc.lpszMenuName  
            = NULL;
                    wc.lpszClassName 
            = NULL;
                    wc.hIconSm       
            = NULL;
                }


            public:

            }
            ;

            int WINAPI WinMain(HINSTANCE hInst, HINSTANCE,
                               LPSTR lpCmd, 
            int nShow)
            {
                KHelloWindow win;

                win.CreateEx(
            0, szProgram, szProgram, WS_POPUP, 00,
                    GetSystemMetrics(SM_CXSCREEN),
                    GetSystemMetrics(SM_CYSCREEN),
                    NULL, NULL, hInst);

                win.ShowWindow(nShow);
                win.UpdateWindow();

                
            return win.MessageLoop();
            }

            posted on 2007-06-02 12:36 思勤無邪 閱讀(2089) 評論(1)  編輯 收藏 引用 所屬分類: C++

            Feedback

            # re: 一個簡單的不依靠MFC的面向對象的Windows程序 2008-05-20 20:00 路過
            基本上沒有封裝,消息處理的太難看了  回復  更多評論
              

            久久乐国产精品亚洲综合| 欧美激情一区二区久久久| 久久久久AV综合网成人| MM131亚洲国产美女久久| 久久国产一区二区| 久久久久国色AV免费观看| 天天影视色香欲综合久久| 欧美亚洲国产精品久久高清 | 91久久香蕉国产熟女线看| 久久久WWW成人免费毛片| 国产精品gz久久久| 久久久久AV综合网成人| 久久久久av无码免费网| 精品多毛少妇人妻AV免费久久| 亚洲中文字幕无码久久2020 | 99久久免费国产特黄| 久久久久久av无码免费看大片| 久久国产精品国语对白| 久久精品国产福利国产琪琪| 日韩中文久久| 亚洲国产欧洲综合997久久| 久久免费大片| 狠狠色噜噜色狠狠狠综合久久 | 久久综合久久综合久久综合| 亚洲午夜无码久久久久| 久久精品亚洲精品国产色婷 | 久久人妻少妇嫩草AV蜜桃| 伊人色综合九久久天天蜜桃| 99久久99久久精品国产| 久久久久国产精品嫩草影院| 久久久久久综合网天天| 66精品综合久久久久久久| 亚洲国产天堂久久久久久| 久久综合狠狠综合久久| 中文字幕久久精品无码| 热99re久久国超精品首页| 亚洲人AV永久一区二区三区久久| 波多野结衣中文字幕久久| 久久99精品久久久久久野外| 久久久久久夜精品精品免费啦| 久久久久九九精品影院|