天山雪莲 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("TEST32", 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("TEST32", 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->m_hWnd == 0)
{
s_pWindowObject->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->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->SetContent("Hello World1!");
int i= pWindow->Create();
pWindow->ShowWindow();
pWindow->UpdateWindow();
CMyWnd * pWindow2 = new CMyWnd;
pWindow2->SetContent("Hello World2!");
pWindow2->Create();
pWindow2->ShowWindow();
pWindow2->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("TEST32", 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->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 ……