LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
SCROLLINFO si;
int iVertPos;
int iHorzPos;
static int cxClient;
static int cyClient;
int iPaintBeg;
int iPaintEnd;
for(int i= iPaintBeg; i< iPaintEnd; ++i)
{
int x = cxChar * (1 - iHorzPos);
int y = cyChar * (i - iVertPos);
const char* p = v[i].c_str();
int lenp = v[i].length();
TextOut(hdc, x, y,
p, lenp);
}
EndPaint (hwnd, &ps);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
SCROLLINFO si;
int iVertPos;
int iHorzPos;
static int cxClient;
static int cyClient;
int iPaintBeg;
int iPaintEnd;
for(int i= iPaintBeg; i< iPaintEnd; ++i)
{
int x = cxChar * (1 - iHorzPos);
int y = cyChar * (i - iVertPos);
const char* p = v[i].c_str();
int lenp = v[i].length();
TextOut(hdc, x, y,
p, lenp);
}
EndPaint (hwnd, &ps);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
TThis is a program written while I am working through Petzolds Programming Windows, based on programs in that book.
It allows you to scroll around a number of permuted alphabetical strings, with the mouse and keyboard.
The problem is that, although it works fine with the default font, when I switch to SYSTEM_FIXED_FONT, the vertical scrolling goes all to hell.
If I force a full repaint, e.g. by minimizing and restoring the window, the output is displayed correctly.
It appears that only downward scrolling is affected, upward and all horizontal scrolling is fine.
Does anyone have any ideas?
I have Windows XP.
Derek
#include <string>
#include <vector>
#include <windows.h>
vector<string>v;
int maxstrlen = 26;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE PrevhInstance, PSTR
szCmdLIne , int iCmdShow)
{
for(int i=0; i<27; ++i)
{
string s;
for(int j = 0; j< 26; ++j)
{
int c = j + i;
if (c > 25)
{
c -= 26;
}
s = s + char(c+97);
};
v.push_back(s);
}
static TCHAR szAppName[] = TEXT ("Hello Win");
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 ("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow (szAppName,
TEXT ("The Keys Program"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
(1024 - 200) / 2,
(768 - 200) / 2,
200,
200,
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;
PAINTSTRUCT ps;
RECT rect;
SCROLLINFO si;
int iVertPos;
int iHorzPos;
static int cxClient;
static int cyClient;
int iPaintBeg;
int iPaintEnd;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
static int cyChar = tm.tmHeight + tm.tmExternalLeading;
static int cxChar = tm.tmAveCharWidth;
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(v.size()-1, iVertPos + ps.rcPaint.bottom / cyChar);
for(int i= iPaintBeg; i< iPaintEnd; ++i)
{
int x = cxChar * (1 - iHorzPos);
int y = cyChar * (i - iVertPos);
const char* p = v[i].c_str();
int lenp = v[i].length();
TextOut(hdc, x, y,
p, lenp);
}
EndPaint (hwnd, &ps);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = v.size()- 1;
si.nPage = cyClient / cyChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = maxstrlen;
si.nPage = cxClient / cxChar;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
return 0;
case WM_VSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
switch(LOWORD(wParam))
{
case SB_TOP:
si.nPos = si.nMin;
break;
case SB_BOTTOM:
si.nPos = si.nMax;
break;
case SB_LINEUP:
--si.nPos;
break;
case SB_LINEDOWN:
++si.nPos;
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;
}
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
if(si.nPos != iVertPos)
{
ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos),
NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_HSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
switch(LOWORD(wParam))
{
case SB_LINELEFT:
--si.nPos;
break;
case SB_LINERIGHT:
++si.nPos;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
}
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
GetScrollInfo(hwnd, SB_HORZ, &si);
if(si.nPos != iHorzPos)
{
ScrollWindow(hwnd, cxChar * (iHorzPos - si.nPos), 0, NULL,
NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_HOME:
SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0);
break;
case VK_END:
SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0);
break;
case VK_PRIOR:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0);
break;
case VK_NEXT:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
break;
case VK_UP:
SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
break;
case VK_DOWN:
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
break;
case VK_LEFT:
SendMessage(hwnd, WM_HSCROLL, SB_LINELEFT, 0);
break;
case VK_RIGHT:
SendMessage(hwnd, WM_HSCROLL, SB_LINERIGHT, 0);
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
his is a program written while I am working through Petzolds Programming Windows, based on programs in that book.
It allows you to scroll around a number of permuted alphabetical strings, with the mouse and keyboard.
The problem is that, although it works fine with the default font, when I switch to SYSTEM_FIXED_FONT, the vertical scrolling goes all to hell.
If I force a full repaint, e.g. by minimizing and restoring the window, the output is displayed correctly.
Does anyone have any ideas?
Derek
#include <string>
#include <vector>
#include <windows.h>
vector<string>v;
int maxstrlen = 26;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE PrevhInstance, PSTR
szCmdLIne , int iCmdShow)
{
for(int i=0; i<27; ++i)
{
string s;
for(int j = 0; j< 26; ++j)
{
int c = j + i;
if (c > 25)
{
c -= 26;
}
s = s + char(c+97);
};
v.push_back(s);
}
static TCHAR szAppName[] = TEXT ("Hello Win");
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 ("This program requires Windows NT!"),
szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow (szAppName,
TEXT ("The Keys Program"),
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
(1024 - 200) / 2,
(768 - 200) / 2,
200,
200,
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;
PAINTSTRUCT ps;
RECT rect;
SCROLLINFO si;
int iVertPos;
int iHorzPos;
static int cxClient;
static int cyClient;
int iPaintBeg;
int iPaintEnd;
switch (message)
{
case WM_CREATE:
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm);
static int cyChar = tm.tmHeight + tm.tmExternalLeading;
static int cxChar = tm.tmAveCharWidth;
ReleaseDC(hwnd, hdc);
return 0;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
iPaintBeg = max(0, iVertPos + ps.rcPaint.top / cyChar);
iPaintEnd = min(v.size()-1, iVertPos + ps.rcPaint.bottom / cyChar);
for(int i= iPaintBeg; i< iPaintEnd; ++i)
{
int x = cxChar * (1 - iHorzPos);
int y = cyChar * (i - iVertPos);
const char* p = v[i].c_str();
int lenp = v[i].length();
TextOut(hdc, x, y,
p, lenp);
}
EndPaint (hwnd, &ps);
return 0;
case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = v.size()- 1;
si.nPage = cyClient / cyChar;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = maxstrlen;
si.nPage = cxClient / cxChar;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
return 0;
case WM_VSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_VERT, &si);
iVertPos = si.nPos;
switch(LOWORD(wParam))
{
case SB_TOP:
si.nPos = si.nMin;
break;
case SB_BOTTOM:
si.nPos = si.nMax;
break;
case SB_LINEUP:
--si.nPos;
break;
case SB_LINEDOWN:
++si.nPos;
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;
}
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
GetScrollInfo(hwnd, SB_VERT, &si);
if(si.nPos != iVertPos)
{
ScrollWindow(hwnd, 0, cyChar * (iVertPos - si.nPos),
NULL, NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_HSCROLL:
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
GetScrollInfo(hwnd, SB_HORZ, &si);
iHorzPos = si.nPos;
switch(LOWORD(wParam))
{
case SB_LINELEFT:
--si.nPos;
break;
case SB_LINERIGHT:
++si.nPos;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
}
si.fMask = SIF_POS;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
GetScrollInfo(hwnd, SB_HORZ, &si);
if(si.nPos != iHorzPos)
{
ScrollWindow(hwnd, cxChar * (iHorzPos - si.nPos), 0, NULL,
NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_KEYDOWN:
switch(wParam)
{
case VK_HOME:
SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0);
break;
case VK_END:
SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0);
break;
case VK_PRIOR:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0);
break;
case VK_NEXT:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
break;
case VK_UP:
SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);
break;
case VK_DOWN:
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
break;
case VK_LEFT:
SendMessage(hwnd, WM_HSCROLL, SB_LINELEFT, 0);
break;
case VK_RIGHT:
SendMessage(hwnd, WM_HSCROLL, SB_LINERIGHT, 0);
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
Have discovered it is not a problem going from default font to SYSTEM_FIXED_FONT, but with any font other than the default font.
Some problem getting the size of the new font?
Derek
Have discovered that some sizes of window do not have problem.
Derek
One of the sizes that does not show proyblem is y = 140 pixels.
Derek
Further information:
if I change THUMBTRACK to THUMBPOSITION, vertical scrolling also works.
Not sure if any one's reading this!
Think I'll just consider the forum my own private notepad.
Derek
In case anyone's interested I found the problem:
a missing = in the code I'd modelled mine on!
Derek