2014-02-09 28 views
3

我目前是win 32 API的初學者,並且正在製作示例程序。我面對的問題是我無法找到合適的方法來設置窗口的最小尺寸,以使窗口內部的文本(居中)在窗口最小時可見。除了當我達到一定的「關鍵」尺寸時,文本在所有其他情況下都是完全可見的,在此之後文本部分被看到或者根本看不到。Win 32 API設置窗口最小尺寸以保持文本完全可見

我發現如何改變窗口的寬度和高度,如下所示:

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)   
{ 
    switch (message)     
    { 
     case WM_DESTROY: 
      PostQuitMessage (0);  
      break; 

     case WM_GETMINMAXINFO: 
      ((MINMAXINFO*)lParam)->ptMinTrackSize.x =100; //apply custom min width 
      ((MINMAXINFO*)lParam)->ptMinTrackSize.y =100; //apply custom min height 
      break; 

     case WM_PAINT: 
     { 
      PAINTSTRUCT ps; 
      HDC hdc = BeginPaint (hwnd, &ps); 

      GetClientRect(hwnd,&rc); 

      DrawText (hdc, TEXT ("Sample text here"), -1, &rc,DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; 


      EndPaint (hwnd, &ps); 
     } 
     break; 

     default:      
      return DefWindowProc (hwnd, message, wParam, lParam); 
    } 

    return 0; 
} 

我覺得這行應該改變,但我不知道需要進行什麼樣的變化。

((MINMAXINFO*)lParam)->ptMinTrackSize.x =100; //apply custom min width 
((MINMAXINFO*)lParam)->ptMinTrackSize.y =100; //apply custom min height 

我的意見是被分配給x和POINT結構的y成員代替顯式的浮點值,一個函數應該被調用,確定該文本的最小寬度和高度。

任何幫助,將不勝感激。

下面是此程序的完整代碼。

#if defined(UNICODE) && !defined(_UNICODE) 
#define _UNICODE 
#elif defined(_UNICODE) && !defined(UNICODE) 
#define UNICODE 
#endif 

#include <tchar.h> 
#include <windows.h> 
#include <stdio.h> 


/* Declare Windows procedure */ 
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 

/* Make the class name into a global variable */ 
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp"); 
RECT rc; 
int WINAPI WinMain (HINSTANCE hThisInstance, 
       HINSTANCE hPrevInstance, 
       LPSTR lpszArgument, 
       int nCmdShow) 
{ 
    HWND hwnd;    /* This is the handle for our window */ 
    MSG messages;   /* Here messages to the application are saved */ 
    WNDCLASSEX wincl;  /* Data structure for the windowclass */ 

    wincl.hInstance = hThisInstance; 
    wincl.lpszClassName = szClassName; 
    wincl.lpfnWndProc = WindowProcedure;  /* This function is called by windows */ 
    wincl.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;     /* Catch double-clicks */ 
    wincl.cbSize = sizeof (WNDCLASSEX); 

    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 
    wincl.lpszMenuName = NULL;     /* No menu */ 
    wincl.cbClsExtra = 0;      /* No extra bytes after the window class */ 
    wincl.cbWndExtra = 0;      /* structure or the window instance */ 

    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; 

    if (!RegisterClassEx (&wincl)) 
     return 0; 

    hwnd = CreateWindowEx (
     0,     /* Extended possibilites for variation */ 
     szClassName,   /* Classname */ 
     _T("Code::Blocks Template Windows App"), 
       /* Title Text */ 
     WS_OVERLAPPEDWINDOW, /* default window */ 
     CW_USEDEFAULT,  /* Windows decides the position */ 
     CW_USEDEFAULT,  /* where the window ends up on the screen */ 
     544,     /* The programs width */ 
     375,     /* and height in pixels */ 
     HWND_DESKTOP,  /* The window is a child-window to desktop */ 
     NULL,    /* No menu */ 
     hThisInstance,  /* Program Instance handler */ 
     NULL     /* No Window Creation data */ 
     ); 

    ShowWindow (hwnd, nCmdShow); 

    while (GetMessage (&messages, NULL, 0, 0)) 
    { 
     TranslateMessage(&messages); 
     DispatchMessage(&messages); 
    } 

    return messages.wParam; 
} 

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message)     
    { 
     case WM_DESTROY: 
      PostQuitMessage (0);  
      break; 

     case WM_GETMINMAXINFO: 
      //window size/position is going to change 
      //apply custom min width/height 350,50 

      SIZE sz; 
      HDC hdc = GetDC(hwnd); 
      TCHAR* myString = TEXT("Sample Text!"); 
      HFONT oldFont, myFont; //create your own font 
      //select your font into device context 
      oldFont = (HFONT)SelectObject(hdc, myFont); 
      //get font dimensions 
      GetTextExtentPoint32(hdc, myString, _tcslen(myString), &sz); 

      ((MINMAXINFO*)lParam)->ptMinTrackSize.x = sz.cx; 
      ((MINMAXINFO*)lParam)->ptMinTrackSize.y = sz.cy; 

      //cleanup 
      SelectObject(hdc, oldFont); 
      DeleteObject(myFont); 
      ReleaseDC(hwnd, hdc); 
      break; 

     case WM_PAINT: 
      { 
       PAINTSTRUCT ps; 
       HDC hdc = BeginPaint (hwnd, &ps); 
       GetClientRect(hwnd,&rc); 
       DrawText (hdc, TEXT("Sample Text!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_WORDBREAK) ; 
       EndPaint (hwnd, &ps); 
      } 
      break; 

     default:      
      return DefWindowProc (hwnd, message, wParam, lParam); 
    } 

    return 0; 
} 

我爲可憐的縮進道歉。

+0

是的,就是這樣做的。 100是任意的而且很小。 –

+0

我編輯了我的答案。嘗試複製和粘貼代碼 - 它應該工作。最好的祝福。 – AlwaysLearningNewStuff

回答

0

我認爲GetTextExtentPoint32是你想要的,所以你可以計算出文本的大小和長度。 Here是顯示如何使用它的示例。

爲防萬一您的文字比您的屏幕尺寸更大,您可以將DT_WORDBREAK標誌添加到您的DrawText調用中 - 請參閱文檔。

您需要創建字體並在設備上下文中選擇它,並且CreateFontIndirect可以幫助您注意LOGFONT structure的成員,以便您可以創建您希望的字體。 Here就是這樣做的一個例子。

嘗試這樣:

case WM_PAINT: 
    { 
     PAINTSTRUCT ps; 
     HDC hdc = BeginPaint (hwnd, &ps); 

     //create your own font 
     HFONT oldFont, myFont; 
     // create logical font for menu 
     LOGFONT lf = { sizeof(lf) }; 
     _tcscpy_s(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), L"Microsoft Sans Serif"); 
     lf.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72); 
     lf.lfWeight = FW_HEAVY; 
     lf.lfItalic = FALSE; 
     lf.lfUnderline = FALSE; 

     myFont = CreateFontIndirect(&lf); 

     //select your font into device context 
     oldFont = (HFONT)SelectObject(hdc, myFont); 

     GetClientRect(hwnd,&rc); 
     DrawText (hdc, TEXT("Sample Text!"), -1, &rc, 
      DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_WORDBREAK) ; 

     //cleanup 
     SelectObject(hdc, oldFont); 
     DeleteObject(myFont); 

     EndPaint (hwnd, &ps); 
    } 
    return 0L; 

case WM_GETMINMAXINFO: 
    { 
     SIZE sz; 
     HDC hdc = GetDC(hwnd); 
     LPTSTR myString = TEXT("Sample text here"); 

     //create your own font 
     HFONT oldFont, myFont; 

     // create logical font for menu 
     LOGFONT lf = { sizeof(lf) }; 
     _tcscpy_s(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), L"Microsoft Sans Serif"); 
     lf.lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72); 
     lf.lfWeight = FW_HEAVY; 
     lf.lfItalic = FALSE; 
     lf.lfUnderline = FALSE; 

     myFont = CreateFontIndirect(&lf); 

     //select your font into device context 
     oldFont = (HFONT)SelectObject(hdc, myFont); 

     //get font dimensions 
     GetTextExtentPoint32(hdc, myString, _tcslen(myString), &sz); 

     ((MINMAXINFO*)lParam)->ptMinTrackSize.x = sz.cx; 
     ((MINMAXINFO*)lParam)->ptMinTrackSize.y = sz.cy; 

     //cleanup 
     SelectObject(hdc, oldFont); 
     DeleteObject(myFont); 
     ReleaseDC(hwnd, hdc); 
    } 
break; 

如果您還有其他問題發表評論。

此致敬禮。

+0

非常感謝您對您的推薦代碼,但是當我嘗試運行它時,編譯器提供了以下錯誤: 1)跨越的初始化「TCHAR * MyString的」 2)跨越的初始化「HDC __ * HDC」 我認爲這是一個明顯的錯誤,但我似乎無法理解其解決方案。 – v01d

+0

我使用代碼塊。我試圖將LPTSTR更改爲TCHAR,但似乎沒有幫助。我認爲這個錯誤也出現在這裏: HDC hdc = GetDC(hwnd); 也可能是錯誤是因爲我在WM_GETMINMAXINFO中重複HDC和String聲明,就像在WM_PAINT中一樣,儘管我不確定它。 無論如何,感謝您的回答,我會將其標記爲有用! – v01d

+0

我發佈了程序的完整代碼。我指定的錯誤是唯一與此問題相關的錯誤(另一個錯誤:跳轉到case標籤) – v01d