查看完整版本: windows

天山雪莲 2004-8-19 19:00

windows

class CMyWnd
{
public:
        BOOL Create()
        {
                //strcpy(m_szBuf,pContent);

                s_pWindowObject = this;
                <!-- CETagParser ~color=#DC143C
<font color="#DC143C">m_hWnd  = 0;<!-- CETagParser ~/color
</font>
                CreateWindow(&quot;TEST32&quot;, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
                  <!-- CETagParser ~color=#A52A2A
<font color="#A52A2A">return (m_hWnd != NULL);<!-- CETagParser ~/color
</font>
        }

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



这是户老师的代码

请问create()不是始终返回  false 吗

omale 2004-8-19 19:47

Re:windows

没看到完整代码,自己猜啊。你标红的那两句之间的CreateWindow应该是个CMyWnd的成员函数,那个函数里面会调用Windows的API CreateWindow或者CreateWindowEx。然后把返回值赋给m_hWnd 。

所以就不会永远返回FALSE,而是创建成功就是TRUE,创建失败就是FALSE。

天山雪莲 2004-8-19 20:41

Re:Re:windows

[quote]
[b]omale: Re:windows[/b]
没看到完整代码,自己猜啊。你标红的那两句之间的CreateWindow应该是个CMyWnd的成员函数,那个函数里面会调用Windows的API CreateWindow或者CreateWindowEx。然后把返回值赋给m_hWnd 。



所以就不会永远返回FALSE,而是创建成功就是TRUE,创建失败就是FALSE。[/quote]

高手
那m_hWnd = 0;
不就没用了吗

天山雪莲 2004-8-19 20:51

Re:windows

class CMyWnd
{
public:
        BOOL Create()
        {
                //strcpy(m_szBuf,pContent);

                s_pWindowObject = this;
                m_hWnd  = 0;
                CreateWindow(&quot;TEST32&quot;, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
                  return (m_hWnd != NULL);
        }

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

        void ShowWindow()
        {
                ::ShowWindow(m_hWnd,SW_SHOW);
        }

        void DestroyWindow()
        {
                ::DestroyWindow(m_hWnd);
        }

        void SetContent(const char * pContent);
        virtual void OnPaint();

        LRESULT MyWndProc(UINT, WPARAM, LPARAM);

        static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

        static CMyWnd* FromHandle(HWND hWnd);

public:
        HWND m_hWnd;
        char m_szBuf[128];
};

void CMyWnd::SetContent(const char * pContent)
{
        strcpy(m_szBuf,pContent);
}


void CMyWnd::OnPaint()
{        
        TCHAR szHello[MAX_LOADSTRING];
        LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
        PAINTSTRUCT ps;
        HDC hdc;
        hdc = BeginPaint(m_hWnd, &ps);
        RECT rt;
        GetClientRect(m_hWnd, &rt);
        DrawText(hdc, m_szBuf, strlen(m_szBuf), &rt, DT_CENTER);
        EndPaint(m_hWnd, &ps);
}

LRESULT CMyWnd::MyWndProc(UINT message, WPARAM wParam, LPARAM lParam)
{
        int wmId, wmEvent;
       
        switch (message)
        {
                case WM_COMMAND:
                        wmId    = LOWORD(wParam);
                        wmEvent = HIWORD(wParam);
                        // Parse the menu selections:
                        switch (wmId)
                        {
                                case IDM_ABOUT:
                                   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, m_hWnd, (DLGPROC)About);
                                   break;
                                case IDM_EXIT:
                                   DestroyWindow();
                                   break;
                                default:
                                   return DefWindowProc(m_hWnd, message, wParam, lParam);
                        }
                        break;
                case WM_PAINT:
                        OnPaint();
                        break;
                case WM_DESTROY:
                        PostQuitMessage(0);
                        break;
                default:
                        return DefWindowProc(m_hWnd, message, wParam, lParam);
   }
   return 0;
}

struct MapHWNDToMyWnd
{
        HWND hWnd;
        CMyWnd* pWindow;
};

CMyWnd* CMyWnd::FromHandle(HWND hWnd)
{
       
        //CMyWnd* pWindow = IsExistsMyWndObject(hWnd);
        CMyWnd* pWindow = (CMyWnd*)::GetWindowLong(hWnd,GWL_USERDATA);

        if  (pWindow)
        {
                return pWindow;
        }
        ::SetWindowLong(hWnd,GWL_USERDATA,(LONG)s_pWindowObject);
        //AddIntoMyWndHWNDMap(s_pWindowObject,hWnd);
       

        if (s_pWindowObject-&gt;m_hWnd == 0)
        {
                s_pWindowObject-&gt;m_hWnd = hWnd;
        }
        return s_pWindowObject;
}

LRESULT CALLBACK CMyWnd::WndProc(HWND hWnd, UINT nMSG, WPARAM wParam, LPARAM lParam)
{
        CMyWnd* pWindow = CMyWnd::FromHandle(hWnd);
        return pWindow-&gt;MyWndProc(nMSG,wParam,lParam);
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
        // TODO: Place code here.
        hInst  = hInstance;
        MSG msg;
        HACCEL hAccelTable;

        // Initialize global strings
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_TEST32, szWindowClass, MAX_LOADSTRING);
        ATOM atom = MyRegisterClass(hInstance);

        CMyWnd * pWindow = new CMyWnd;
        pWindow-&gt;SetContent(&quot;Hello World1!&quot;);
       
        int i= pWindow-&gt;Create();
        pWindow-&gt;ShowWindow();
        pWindow-&gt;UpdateWindow();


        CMyWnd *  pWindow2 = new CMyWnd;
       
        pWindow2-&gt;SetContent(&quot;Hello World2!&quot;);

        pWindow2-&gt;Create();
        pWindow2-&gt;ShowWindow();
        pWindow2-&gt;UpdateWindow();

        hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TEST32);

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

        return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//

ATOM MyRegisterClass(HINSTANCE hInstance)
{
        WNDCLASSEX wcex;

        ZeroMemory(&wcex,sizeof(wcex));

        wcex.cbSize = sizeof(WNDCLASSEX);
        wcex.style                        = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc        = (WNDPROC)CMyWnd::WndProc;
        wcex.cbClsExtra                = 0;
        wcex.cbWndExtra                = 0;
        wcex.hInstance                = hInstance;
        wcex.hIcon                        = LoadIcon(hInstance, (LPCTSTR)IDI_TEST32);
        wcex.hCursor                = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground        = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName        = (LPCSTR)IDC_TEST32;
        wcex.lpszClassName        = szWindowClass;
        //wcex.hIconSm                = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

        return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//


//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND        - process the application menu
//  WM_PAINT        - Paint the main window
//  WM_DESTROY        - post a quit message and return
//
//


// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
        switch (message)
        {
                case WM_INITDIALOG:
                                return TRUE;

                case WM_COMMAND:
                        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
                        {
                                EndDialog(hDlg, LOWORD(wParam));
                                return TRUE;
                        }
                        break;
        }
    return FALSE;
}










这下代码都有了
可还是不明白



m_hWnd 并没有传递给CreateWindow 呀
CreateWindow是库函数
怎么察看源代码呢
我把m_hWnd换个名字
CreateWindow怎么 把返回值付给我定义的变量呢

omale 2004-8-20 13:00

Re:windows

看错鸟。CreateWindow就是全局的windows API。
Create就是封装CreateWindow的成员函数。
我没编译运行试过。
但是,真的这就是原版代码的话,Create函数就如你说的会永远返回FALSE。
我觉得那两句应该写成这样:

m_hWnd = CreateWindow(&quot;TEST32&quot;, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInst, NULL);
return (m_hWnd != NULL);

hahahah 2004-8-20 19:54

Re:windows

这是户老师的源代码
只不过我调试的时候
create返回的是1
不知道什么原因

omale 2004-8-20 20:52

Re:windows

又看错鸟..... 看来偶没有编译器眼睛看代码的水平还有待提高:-(
看看WndProc函数:

LRESULT CALLBACK CMyWnd::WndProc(HWND hWnd, UINT nMSG, WPARAM wParam, LPARAM lParam)
{
        CMyWnd* pWindow = CMyWnd::FromHandle(hWnd);
        return pWindow-&gt;MyWndProc(nMSG,wParam,lParam);
}

就是这一句,会调用FromHandle方法。
CMyWnd* pWindow = CMyWnd::FromHandle(hWnd);
然后FromHandle方法里面就会给m_hWnd赋值。

调用CreateWindow API的时候,系统多次调用WndProc,发送包括WM_CREATE等消息。所以FromHandle会被调用,所以m_hWnd就被赋值了。这个机制根MFC的差不多。

哈希 2004-8-21 09:03

Re:Re:windows

[quote]
[b]omale: Re:windows[/b]
LRESULT CALLBACK CMyWnd::WndProc(HWND hWnd, UINT nMSG, WPARAM wParam, LPARAM lParam)[/quote]
哦!我在研究户Sir代码时也查过该问题,猜的和Omale大哥差不多,谢谢大哥证实。 [img]http://bbs.tongji.net/images/smiles/bigsmile.gif[/img]

fred_huxf 2004-10-9 12:12

Re:windows

你们讨论的很好呀

OwnWaterloo 2008-10-7 23:11

楼上是户sir?

记得户sir的课件里, 对C++对象封装窗口时处理HWND和this的映射, 提到了3种办法:
1.塞到USER_DATA
2.全局表
这2种讨论得非常多了

迟迟不见户sir讨论的是最高效的mapping技术
3.Thunk ……
页: [1]
查看完整版本: windows