最近寫程式是,給整個界面換了字型,卻發現不對勁,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);
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);來實作的(可以通過程式得知)。