最近写程序是,给整个界面换了字体,却发现不对劲,Edit控件里的text并不左对齐了,而是向右移了几个像素,后来发现问题出现在没有在设置完字体后,再设置Edit控件里的margin(left and right) 。于是做了些实验来看看他们的关系:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE:
hWndDropDown = CreateWindow(_T("COMBOBOX"),_T("t"),WS_POPUP |CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP|WS_VISIBLE ,0,0,100,100,
hWnd,0,hInst,NULL);
MoveWindow(hWndDropDown,20,20,50,50,true);
hEdit = CreateWindow(_T("Edit"),NULL,WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT | ES_WANTRETURN | ES_MULTILINE,
20,20,30,30,hWnd,0,hInst,NULL);
if(!EditWndProc)
{
EditWndProc = (WNDPROC)GetClassLong(hEdit,GCL_WNDPROC);
}
SetWindowLong(hEdit,GWL_WNDPROC,(LONG_PTR)EditSubWndProc);
//--------------------------------------------------------------
PopOutLastErr();
//---------------------------------------------------------------
MoveWindow(hEdit,30,30,60,60,true);
//WM_SETFONT消息的执行,会让hEdit的Margin发生变化
SendMessage(hEdit,WM_SETFONT,(WPARAM)GetMyFont(),MAKELONG(0,0));
//SendMessage( hEdit, EM_SETMARGINS,EC_LEFTMARGIN,MAKELPARAM(0,0));
SendMessage(hWndDropDown,WM_SETFONT,(WPARAM)GetMyFont(),MAKELONG(0,0));
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
RECT rt;
//HDC hdc = GetDC(hWnd);
GetClientRect(hWnd,&rt);
HBRUSH hBrush = CreateSolidBrush(RGB(255,0,0));
HBRUSH hOrigBrush = (HBRUSH)SelectObject(hdc,hBrush/*GetStockObject((int)hBrush)*/);
SelectObject(hdc,GetStockObject(NULL_PEN));
Rectangle(hdc,rt.left,rt.top,rt.right,rt.bottom);
SelectObject(hdc,hOrigBrush);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// 下面是hEdit的响应函数(Proc)
LRESULT CALLBACK EditSubWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SETFONT:
{
LRESULT res = CallWindowProc(EditWndProc,hWnd,message,wParam,lParam);
if(res)
{
SendMessage(hWnd,EM_SETMARGINS,EC_LEFTMARGIN,MAKELONG(0,0));
}
//break;
return res;
}
}
return CallWindowProc(EditWndProc,hWnd,message,wParam,lParam);
}
从上面的WndProc中的WM_CREATE消息中可知:hEdit通过SendMessage(hEdit,WM_SETFONT,(WPARAM)GetMyFont(),MAKELONG(0,0));后,hEdit的Margin发生了变化,所以要设置hEdit的Margin对齐,所以要在之后设置SendMessage( hEdit, EM_SETMARGINS,EC_LEFTMARGIN,MAKELPARAM(0,0)); ,但是本文却不这样做,因为在一个大的工程里,设置字体是
很常见的,而SendMessage( hEdit, EM_SETMARGINS,EC_LEFTMARGIN,MAKELPARAM(0,0));是对设置完的字体后进行对齐,如果在SendMessage( hEdit, EM_SETMARGINS,EC_LEFTMARGIN,MAKELPARAM(0,0));之后又有设置字体的消息,那么
这样设置margin对齐也不管用了,这在大的工程里是很常见的。所以本文直接在hEdit的消息响应函数(EditSubWndProc)里针对WM_SETFONT消息来对其进行EM_SETMARGINS(设置margin) 。这样只要有WM_SETFONT消息,就有对应的EM_SETMARGINS消息。但是只有EditSubWndProc是对windows定义的Edit的消息响应函数的改写,所以自己设置的WM_SETFONT消息一定要先响应windows定义的Edit消息响应函数里的WM_SETFONT,这是通过自己设置的WM_SETFONT里的LRESULT res = CallWindowProc(EditWndProc,hWnd,message,wParam,lParam);来实现的(可以通过程序得知)。