问题描述
- vs中编写了一个会显示水平和竖直滚动条的程序,但是运行时出现错误的结果,请问这是为啥?
-
这是源代码:
#include
#include"resource.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
static char szAppName[] = "SysMets2";
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
if (!hPrevInstance)
{
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;RegisterClass(&wndclass); } hwnd = CreateWindow(szAppName, "Get System Metrics No.2", WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ShowWindow(hwnd, nCmdShow); 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)
{
static short cxChar, cxCaps, cyChar, cxClient, cyClient, nHscrollPos,nMaxWidth,nVscrollPos,nVscrollMax,nHscrollMax;
char szBuffer[10];
HDC hdc;
short i,x,y,nPaintBeg,nPaintEnd,nVscrollInc,nHscrollInc;
PAINTSTRUCT ps;
TEXTMETRIC tm;switch (message) { case WM_CREATE: hdc = GetDC(hwnd); GetTextMetrics(hdc, &tm); cxChar = tm.tmAveCharWidth; cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2)*cxChar / 2; cyChar = tm.tmHeight + tm.tmExternalLeading; ReleaseDC(hwnd, hdc); nMaxWidth = 40 * cxChar + 18 * cxCaps; return 0; case WM_SIZE: cyClient = HIWORD(lParam); cxClient = LOWORD(lParam); nVscrollMax = max(0, NUMLINES + 2 - cyClient / cyChar); nVscrollPos = min(nVscrollPos, nVscrollMax); SetScrollRange(hwnd, SB_VERT, 0, nVscrollMax, FALSE); SetScrollPos(hwnd, SB_VERT, nVscrollPos, TRUE); nHscrollMax = max(0, 2 + (nMaxWidth - cxClient) / cxChar); nHscrollPos = min(nHscrollPos, nHscrollMax); SetScrollRange(hwnd, SB_HORZ, 0, nHscrollMax, FALSE); SetScrollPos(hwnd, SB_HORZ, nHscrollPos, TRUE); return 0; case WM_VSCROLL: switch (wParam) { case SB_TOP: nVscrollInc = -nVscrollPos; break; case SB_BOTTOM: nVscrollInc = nVscrollMax - nVscrollPos; break; case SB_LINEUP: nVscrollInc = -1; break; case SB_LINEDOWN: nVscrollInc = 1; case SB_PAGEUP: nVscrollPos = min(-1, -cyClient / cyChar); break; case SB_PAGEDOWN: nVscrollPos = max(1, cyClient / cyChar); break; case SB_THUMBTRACK: nVscrollInc = LOWORD(lParam) - nVscrollPos; break; default: nVscrollInc = 0; } if (nVscrollInc == max(-nVscrollPos, min(nVscrollInc, nVscrollMax - nVscrollPos))) { nVscrollPos += nVscrollInc; ScrollWindow(hwnd, 0, -cyChar*nVscrollInc, NULL, NULL); SetScrollPos(hwnd, SB_VERT, nVscrollPos, TRUE); UpdateWindow(hwnd); } return 0; case WM_HSCROLL: switch (wParam) { case SB_LINEDOWN: nHscrollPos = 1; break; case SB_LINEUP: nHscrollPos =- 1; break; case SB_PAGEUP: nHscrollPos = -8; break; case SB_PAGEDOWN: nHscrollPos = 8; break; case SB_THUMBPOSITION: nHscrollInc = LOWORD(lParam) - nHscrollPos; break; default: nHscrollInc=0; } if (nHscrollPos = max(-nHscrollPos, min(nHscrollInc, nHscrollMax - nHscrollPos))) { nHscrollPos += nHscrollInc; ScrollWindow(hwnd, -cxChar*nHscrollInc, 0, NULL, NULL); SetScrollPos(hwnd, SB_HORZ, nHscrollPos, TRUE); } return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); nPaintBeg = max(0,nVscrollPos+ps.rcPaint.top/cyChar-1); nPaintEnd = min(NUMLINES,nVscrollPos=ps.rcPaint.bottom/cyChar); for (i = nPaintBeg; i < nPaintEnd; i++) { x = cxChar*(1-nHscrollPos); y = cyChar*(1-nVscrollPos+i); TextOut(hdc,cxChar,y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel) ); TextOut(hdc, x+18*cxCaps,y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc) ); SetTextAlign(hdc,TA_RIGHT | TA_TOP); TextOut(hdc,x+18*cxCaps+40*cxChar, y, szBuffer, wsprintf(szBuffer, "%5d", GetSystemMetrics(sysmetrics[i].nIndex)) ); SetTextAlign(hdc, TA_LEFT| TA_TOP); } EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam);
}
这是resource.h中的代码:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Win32Project1.rc// 新对象的下一组默认值
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
#define NUMLINES (sizeof sysmetrics/sizeof sysmetrics[0])
struct
{
int nIndex;
char *szLabel;
char *szDesc;}
sysmetrics[] =
{
SM_CXSCREEN, "SM_CXSCREEN", "Screen with in pixels",
SM_CYSCREEN, "SM_CYSCREEN", "Screen height in pixels",
SM_CXVSCROLL, "SM_CXVSCROLL", "Vertical scroll arrow width",
SM_CYHSCROLL, "SM_CYHSCROLL", "Horizontal scroll arrow height",
SM_CYCAPTION, "SM_CYCAPTION", "Caption bar height",
SM_CXBORDER, "SM_CXBORDER", "border width",
SM_CYBORDER, "SM_CYBORDER", "border height",
SM_CXDLGFRAME, "SM_CXDLGFRAME", "Dialog window frame width",
SM_CYDLGFRAME, "SM_CYDLGFRAME", "Dialog window frame height",
SM_CYVTHUMB, "SM_CYVTHUMB", "Vertical scroll thumb height",
SM_CXHTHUMB, "SM_CXHTHUMB", "Horizontal scroll thumb height",
SM_CXICON, "SM_CXICON", "Icon width",
SM_CYICON, "SM_CYICON", "icon height",
SM_CXCURSOR, "SM_CXCURSOR", "Cursor width",
SM_CYCURSOR, "SM_CYCURSOR", "Cursor height",
SM_CYMENU, "SM_CYMENU", "Menu bar height",
SM_CXFULLSCREEN, "SM_CXFULLSCREEN", "Full-screen client window width",
SM_CYFULLSCREEN, "SM_CYFULLSCREEN", "Full-screen client window height",
SM_CYKANJIWINDOW, "SM_CYKANJIWINDOW", "Kanji window height",
SM_MOUSEPRESENT, "SM_MOUSEPRESENT", "Mouse present flag",
SM_CYVSCROLL, "SM_CYVSCROLL", "vertical scroll arrow height",
SM_CXHSCROLL, "SM_CXHSCROLL", "Horiozntal scroll arrow width",
SM_DEBUG, "SM_DEBUG", "Debug version flag",
SM_SWAPBUTTON, "SM_SWAPBUTTON", "Mouse buttons swapped flag",
SM_RESERVED1, "SM_RESERVED1", "Reserved",
SM_RESERVED2, "SM_RESERVED2", "Reserved",
SM_RESERVED3, "SM_RESERVED3", "Reserved",
SM_RESERVED4, "SM_RESERVED4", "Reserved",
SM_CXMIN, "SM_CXMIN", "Mininum window width",
SM_CYMIN, "SM_CYMIN", "Mininum window height",
SM_CXSIZE, "SM_CXSIZE", "Minimize/Maximize icon width",
SM_CYSIZE, "SM_CYSIZE", "Minimize/Maximize icon height",
SM_CXFRAME, "SM_CXFRAME", "Window frame width",
SM_CYFRAME, "SM_CYFRAME", "Window frame height",
SM_CXMINTRACK, "SM_CXMINTRACK", "Minimize tracking width of window",
SM_CYMINTRACK, "SM_CYMINTRACK", "Minimize tracking height of window",
SM_CMETRICS, "SM_CMETRICS", "Number of system metrics"
};
解决方案
处理滚动条时的常见问题。
就是你首先要有显示内容的大小。其次在 WM_SIZE 中要算出有无水平、竖直滚动条时的4种客户区大小,直接选定1种,设定是否显示滚动条,避免反复调整。最后还要设定一个标志变量,跳过在 WM_SIZE 消息中更改滚动条而再次触发的 WM_SIZE 消息。
最简单的处理方案其实是让滚动条始终显示。
解决方案二:
单步调试一下,看出错的具体语句是什么