天天看點

SendMessage(HWND, WM_SETFONT,lParam,wParam) and SendMessage(HWND,EM_SETMARGINS,lParam,wParam)

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