当我调整窗口大小然后使用scollbar时,文本会被剪裁。当我再次调整窗口大小时,剪切的文本再次正确显示。
为什么会发生这种情况,我该如何预防?
截图: http://i.imgur.com/CLHgowx.png
main.cpp中:
#include <Windows.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Scratch");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Scratch"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
TEXTMETRIC tm;
PAINTSTRUCT ps;
SCROLLINFO si;
static int cxChar, cyChar, cxClient, cyClient, cxCaps;
int i, y, iPaintBeg, iPaintEnd, iVertPos;
TCHAR buffer[10];
switch(message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &tm);
cxChar = tm.tmAveCharWidth;
cyChar = tm.tmHeight + tm.tmExternalLeading;
cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
ReleaseDC(hwnd, hdc);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_PAGE | SIF_RANGE;
si.nMin = 0;
si.nMax = NUMLINES - 1;
si.nPage = cyClient / cyChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(NUMLINES - 1, iVertPos + ps.rcPaint.bottom / cyChar);
for (i = iPaintBeg; i < iPaintEnd; i++)
{
y = cyChar * (i - iVertPos);
TextOut(hdc, 0, y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));
TextOut(hdc, 22 * cxCaps, y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc));
SetTextAlign(hdc, TA_TOP | TA_RIGHT);
TextOut(hdc, 60 * cxCaps, y, buffer, wsprintf(buffer, TEXT("%5d") ,GetSystemMetrics(sysmetrics[i].iIndex)));
SetTextAlign(hdc, TA_TOP | TA_LEFT);
}
EndPaint(hwnd, &ps);
return 0;
case WM_VSCROLL:
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
switch (LOWORD(wParam))
{
case SB_LINEUP:
si.nPos -= 1;
break;
case SB_LINEDOWN:
si.nPos += 1;
break;
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default:
break;
}
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
if(iVertPos != si.nPos)
{
ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL);
}
UpdateWindow(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
sysmets.h(定义NUMLINES和sysmetrics结构)
#ifndef SYSMETS_H_
#define SYSMETS_H_
#include <windows.h>
#define NUMLINES ((int) sizeof(sysmetrics) / sizeof(sysmetrics[0]))
struct
{
int iIndex;
TCHAR *szLabel;
TCHAR *szDesc;
}
sysmetrics [] =
{
SM_CXSCREEN, TEXT("SM_CXSCREEN"), TEXT("Screen Width in pixels."),
SM_CYSCREEN, TEXT("SM_CYSCREEN"), TEXT("Screen Height in pixels."),
SM_CXVSCROLL, TEXT("SM_CXVSCROLL"), TEXT("Vertical Scroll Width"),
SM_CYHSCROLL, TEXT("SM_CYHSCROLL"), TEXT("Horizontal Scroll Height"),
SM_CYCAPTION, TEXT("SM_CYCAPTION"), TEXT("Caption Bar Height"),
SM_CXBORDER, TEXT("SM_CXBORDER"), TEXT("Window Border Width"),
SM_CYBORDER, TEXT("SM_CYBORDER"), TEXT("Window Border Height"),
SM_CXFIXEDFRAME, TEXT("SM_CXFIXEDFRAME"), TEXT("Dialog Window Frame Width"),
SM_CYFIXEDFRAME, TEXT("SM_CYFIXEDFRAME"), TEXT("Dialog Window Frame Height"),
SM_CYVTHUMB, TEXT("SM_CYVTHUMB"), TEXT("Vertical scroll thumb height"),
SM_CXHTHUMB, TEXT("SM_CXHTHUMB"), TEXT("Horizontal scroll thumb width"),
SM_CXICON, TEXT("SM_CXICON"), TEXT("Icon width"),
SM_CYICON, TEXT("SM_CYICON"), TEXT("Icon height"),
SM_CXCURSOR, TEXT("SM_CXCURSOR"), TEXT("Cursor width"),
SM_CYCURSOR, TEXT("SM_CYCURSOR"),TEXT("Cursor height"),
SM_CYMENU, TEXT("SM_CYMENU"), TEXT("Menu bar height"),
SM_CXFULLSCREEN, TEXT("SM_CXFULLSCREEN"), TEXT("Full screen client area width"),
SM_CYFULLSCREEN, TEXT("SM_CYFULLSCREEN"), TEXT("Full screen client area height"),
SM_CYKANJIWINDOW, TEXT("SM_CYKANJIWINDOW"), TEXT("Kanji window height"),
SM_MOUSEPRESENT, TEXT("SM_MOUSEPRESENT"), TEXT("Mouse present flag"),
SM_CYVSCROLL, TEXT("SM_CYVSCROLL"), TEXT("Vertical scroll arrow height"),
SM_CXHSCROLL, TEXT("SM_CXHSCROLL"), TEXT("Horizontal scroll arrow width"),
SM_DEBUG, TEXT("SM_DEBUG"), TEXT("Debug version flag"),
SM_SWAPBUTTON, TEXT("SM_SWAPBUTTON"), TEXT("Mouse buttons swapped flag"),
SM_CXMIN, TEXT("SM_CXMIN"), TEXT("Minimum window width"),
SM_CYMIN, TEXT("SM_CYMIN"), TEXT("Minimum window height"),
SM_CXSIZE, TEXT("SM_CXSIZE"), TEXT("Min/Max/Close button width"),
SM_CYSIZE, TEXT("SM_CYSIZE"), TEXT("Min/Max/Close button height"),
SM_CXSIZEFRAME, TEXT("SM_CXSIZEFRAME"), TEXT("Window sizing frame width"),
SM_CYSIZEFRAME, TEXT("SM_CYSIZEFRAME"), TEXT("Window sizing frame height"),
SM_CXMINTRACK, TEXT("SM_CXMINTRACK"), TEXT("Minimum window tracking width"),
SM_CYMINTRACK, TEXT("SM_CYMINTRACK"), TEXT("Minimum window tracking height"),
SM_CXDOUBLECLK, TEXT("SM_CXDOUBLECLK"), TEXT("Double click x tolerance"),
SM_CYDOUBLECLK, TEXT("SM_CYDOUBLECLK"), TEXT("Double click y tolerance"),
SM_CXICONSPACING, TEXT("SM_CXICONSPACING"), TEXT("Horizontal icon spacing"),
SM_CYICONSPACING, TEXT("SM_CYICONSPACING"), TEXT("Vertical icon spacing"),
SM_MENUDROPALIGNMENT, TEXT("SM_MENUDROPALIGNMENT"), TEXT("Left or right menu drop"),
SM_PENWINDOWS, TEXT("SM_PENWINDOWS"), TEXT("Pen extensions installed"),
SM_DBCSENABLED, TEXT("SM_DBCSENABLED"), TEXT("Double-Byte Char Set enabled"),
SM_CMOUSEBUTTONS, TEXT("SM_CMOUSEBUTTONS"), TEXT("Number of mouse buttons"),
SM_SECURE, TEXT("SM_SECURE"), TEXT("Security present flag"),
SM_CXEDGE, TEXT("SM_CXEDGE"), TEXT("3-D border width"),
SM_CYEDGE, TEXT("SM_CYEDGE"), TEXT("3-D border height"),
SM_CXMINSPACING, TEXT("SM_CXMINSPACING"), TEXT("Minimized window spacing width"),
SM_CYMINSPACING, TEXT("SM_CYMINSPACING"), TEXT("Minimized window spacing height"),
SM_CXSMICON, TEXT("SM_CXSMICON"), TEXT("Small icon width"),
SM_CYSMICON, TEXT("SM_CYSMICON"), TEXT("Small icon height"),
SM_CYSMCAPTION, TEXT("SM_CYSMCAPTION"), TEXT("Small caption height"),
SM_CXSMSIZE, TEXT("SM_CXSMSIZE"), TEXT("Small caption button width"),
SM_CYSMSIZE, TEXT("SM_CYSMSIZE"), TEXT("Small caption button height"),
SM_CXMENUSIZE, TEXT("SM_CXMENUSIZE"), TEXT("Menu bar button width"),
SM_CYMENUSIZE, TEXT("SM_CYMENUSIZE"), TEXT("Menu bar button height"),
SM_ARRANGE, TEXT("SM_ARRANGE"), TEXT("How minimized windows arranged"),
SM_CXMINIMIZED, TEXT("SM_CXMINIMIZED"), TEXT("Minimized window width"),
SM_CYMINIMIZED, TEXT("SM_CYMINIMIZED"), TEXT("Minimized window height"),
SM_CXMAXTRACK, TEXT("SM_CXMAXTRACK"), TEXT("Maximum draggable width"),
SM_CYMAXTRACK, TEXT("SM_CYMAXTRACK"), TEXT("Maximum draggable height"),
SM_CXMAXIMIZED, TEXT("SM_CXMAXIMIZED"), TEXT("Width of maximized window"),
SM_CYMAXIMIZED, TEXT("SM_CYMAXIMIZED"), TEXT("Height of maximized window"),
SM_NETWORK, TEXT("SM_NETWORK"), TEXT("Network present flag"),
SM_CLEANBOOT, TEXT("SM_CLEANBOOT"), TEXT("How system was booted"),
SM_CXDRAG, TEXT("SM_CXDRAG"), TEXT("Avoid drag x tolerance"),
SM_CYDRAG, TEXT("SM CYDRAG"), TEXT("Avoid drag y tolerance"),
SM_SHOWSOUNDS, TEXT("SM_SHOWSOUNDS"), TEXT("Present sounds visually"),
SM_CXMENUCHECK, TEXT("SM_CXMENUCHECK"), TEXT("Menu check-mark width"),
SM_CYMENUCHECK, TEXT("SM_CYMENUCHECK"), TEXT("Menu check-mark height"),
SM_SLOWMACHINE, TEXT("SM_SLOWMACHINE"), TEXT("Slow processor flag"),
SM_MIDEASTENABLED, TEXT("SM_MIDEASTENABLED"), TEXT("Hebrew and Arabic enabled flag"),
SM_MOUSEWHEELPRESENT, TEXT("SM_MOUSEWHEELPRESENT"), TEXT("Mouse wheel present flag"),
SM_XVIRTUALSCREEN, TEXT("SM_XVIRTUALSCREEN"), TEXT("Virtual screen x origin"),
SM_YVIRTUALSCREEN, TEXT("SM_YVIRTUALSCREEN"), TEXT("Virtual screen y origin"),
SM_CXVIRTUALSCREEN, TEXT("SM_CXVIRTUALSCREEN"), TEXT("Virtual screen width"),
SM_CYVIRTUALSCREEN, TEXT("SM_CYVIRTUALSCREEN"), TEXT("Virtual screen height"),
SM_CMONITORS, TEXT("SM_CMONITORS"), TEXT("Number of monitors"),
SM_SAMEDISPLAYFORMAT, TEXT("SM_SAMEDISPLAYFORMAT"), TEXT("Same color format flag")
};
#endif
答案 0 :(得分:2)
关于UpdateWindow
的MSDN:
该函数直接向窗口过程发送WM_PAINT消息 指定窗口的一个,绕过应用程序队列。 如果 更新区域为空,不会发送任何消息。
要强制进行更新,您可以使用
手动设置更新区域InvalidateRect(hwnd, NULL, TRUE)
这会在hwnd的消息队列中添加WM_PAINT
消息。如果您想强制立即重新绘制,您可以立即致电UpdateWindow
,但这不是必需的。