Win 32 API设置窗口最小大小,以使文本完全可见

时间:2014-02-09 09:34:59

标签: api winapi window

我目前是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

我的想法是,改为分配给POINT结构的x和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;
}

我为糟糕的缩进道歉。

1 个答案:

答案 0 :(得分:0)

我认为GetTextExtentPoint32是您想要的,因此您可以计算文本大小和长度。 Here是显示如何使用它的示例。

万一您的文字尺寸大于屏幕尺寸,您可以在DrawText电话中添加DT_WORDBREAK标记 - 请参阅文档。

您需要创建字体并在设备上下文中选择它,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;

如果您还有其他问题,请发表评论。

最好的问候。