602 lines
16 KiB
C
602 lines
16 KiB
C
/* NetHack 3.5 mhmsgwnd.c $Date$ $Revision$ */
|
|
/* Copyright (C) 2001 by Alex Kompel */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "winMS.h"
|
|
#include "mhmsgwnd.h"
|
|
#include "mhmsg.h"
|
|
#include "mhcmd.h"
|
|
#include "mhfont.h"
|
|
#include "mhcolor.h"
|
|
|
|
#define MSG_WRAP_TEXT
|
|
|
|
#define MSG_VISIBLE_LINES max(iflags.wc_vary_msgcount, 2)
|
|
#define MAX_MSG_LINES 32
|
|
#define MSG_LINES (int)min(iflags.msg_history, MAX_MSG_LINES)
|
|
#define MAXWINDOWTEXT 200
|
|
|
|
struct window_line {
|
|
int attr;
|
|
char text[MAXWINDOWTEXT];
|
|
};
|
|
|
|
typedef struct mswin_nethack_message_window {
|
|
size_t max_text;
|
|
struct window_line window_text[MAX_MSG_LINES];
|
|
|
|
int xChar; /* horizontal scrolling unit */
|
|
int yChar; /* vertical scrolling unit */
|
|
int xUpper; /* average width of uppercase letters */
|
|
int xPos; /* current horizontal scrolling position */
|
|
int yPos; /* current vertical scrolling position */
|
|
int xMax; /* maximum horizontal scrolling position */
|
|
int yMax; /* maximum vertical scrolling position */
|
|
int xPage; /* page size of horizontal scroll bar */
|
|
int lines_last_turn; /* lines added during the last turn */
|
|
int dont_care; /* flag the the user does not care if messages are lost */
|
|
} NHMessageWindow, *PNHMessageWindow;
|
|
|
|
static TCHAR szMessageWindowClass[] = TEXT("MSNHMessageWndClass");
|
|
LRESULT CALLBACK NHMessageWndProc(HWND, UINT, WPARAM, LPARAM);
|
|
static void register_message_window_class();
|
|
static void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
static void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
#ifndef MSG_WRAP_TEXT
|
|
static void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
#endif
|
|
static COLORREF setMsgTextColor(HDC hdc, int gray);
|
|
static void onPaint(HWND hWnd);
|
|
static void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
|
|
#ifdef USER_SOUNDS
|
|
extern void play_sound_for_message(const char* str);
|
|
#endif
|
|
|
|
HWND mswin_init_message_window () {
|
|
static int run_once = 0;
|
|
HWND ret;
|
|
DWORD style;
|
|
|
|
if( !run_once ) {
|
|
register_message_window_class( );
|
|
run_once = 1;
|
|
}
|
|
|
|
#ifdef MSG_WRAP_TEXT
|
|
style = WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL;
|
|
#else
|
|
style = WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL;
|
|
#endif
|
|
|
|
ret = CreateWindow(
|
|
szMessageWindowClass, /* registered class name */
|
|
NULL, /* window name */
|
|
style, /* window style */
|
|
0, /* horizontal position of window */
|
|
0, /* vertical position of window */
|
|
0, /* window width */
|
|
0, /* window height - set it later */
|
|
GetNHApp()->hMainWnd, /* handle to parent or owner window */
|
|
NULL, /* menu handle or child identifier */
|
|
GetNHApp()->hApp, /* handle to application instance */
|
|
NULL ); /* window-creation data */
|
|
|
|
if( !ret ) panic("Cannot create message window");
|
|
|
|
return ret;
|
|
}
|
|
|
|
void register_message_window_class()
|
|
{
|
|
WNDCLASS wcex;
|
|
ZeroMemory( &wcex, sizeof(wcex));
|
|
|
|
wcex.style = CS_NOCLOSE;
|
|
wcex.lpfnWndProc = (WNDPROC)NHMessageWndProc;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = GetNHApp()->hApp;
|
|
wcex.hIcon = NULL;
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = mswin_get_brush(NHW_MESSAGE, MSWIN_COLOR_BG);
|
|
wcex.lpszMenuName = NULL;
|
|
wcex.lpszClassName = szMessageWindowClass;
|
|
|
|
RegisterClass(&wcex);
|
|
}
|
|
|
|
LRESULT CALLBACK NHMessageWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_CREATE:
|
|
onCreate( hWnd, wParam, lParam );
|
|
break;
|
|
|
|
case WM_MSNH_COMMAND:
|
|
onMSNHCommand(hWnd, wParam, lParam);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
onPaint(hWnd);
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
SetFocus(GetNHApp()->hMainWnd);
|
|
break;
|
|
|
|
#ifndef MSG_WRAP_TEXT
|
|
case WM_HSCROLL:
|
|
onMSNH_HScroll(hWnd, wParam, lParam);
|
|
break;
|
|
#endif
|
|
|
|
case WM_VSCROLL:
|
|
onMSNH_VScroll(hWnd, wParam, lParam);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
{
|
|
PNHMessageWindow data;
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
free(data);
|
|
SetWindowLong(hWnd, GWL_USERDATA, (LONG)0);
|
|
} break;
|
|
|
|
case WM_SIZE:
|
|
{
|
|
SCROLLINFO si;
|
|
int xNewSize;
|
|
int yNewSize;
|
|
PNHMessageWindow data;
|
|
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
|
|
xNewSize = LOWORD(lParam);
|
|
yNewSize = HIWORD(lParam);
|
|
|
|
if( xNewSize>0 || yNewSize>0 ) {
|
|
|
|
#ifndef MSG_WRAP_TEXT
|
|
data->xPage = xNewSize/data->xChar;
|
|
data->xMax = max(0, (int)(1 + data->max_text - data->xPage));
|
|
data->xPos = min(data->xPos, data->xMax);
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
si.nMin = 0;
|
|
si.nMax = data->max_text;
|
|
si.nPage = data->xPage;
|
|
si.nPos = data->xPos;
|
|
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
|
|
#endif
|
|
|
|
data->yMax = MSG_LINES-1;
|
|
data->yPos = min(data->yPos, data->yMax);
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
si.nMin = MSG_VISIBLE_LINES;
|
|
si.nMax = data->yMax + MSG_VISIBLE_LINES - 1;
|
|
si.nPage = MSG_VISIBLE_LINES;
|
|
si.nPos = data->yPos;
|
|
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHMessageWindow data;
|
|
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
switch( wParam ) {
|
|
case MSNH_MSG_PUTSTR:
|
|
{
|
|
PMSNHMsgPutstr msg_data = (PMSNHMsgPutstr)lParam;
|
|
SCROLLINFO si;
|
|
char* p;
|
|
|
|
if( msg_data->append ) {
|
|
strncat(data->window_text[MSG_LINES-1].text, msg_data->text,
|
|
MAXWINDOWTEXT - strlen(data->window_text[MSG_LINES-1].text));
|
|
} else {
|
|
/* check if the string is empty */
|
|
for(p = data->window_text[MSG_LINES-1].text; *p && isspace(*p); p++);
|
|
|
|
if( *p ) {
|
|
/* last string is not empty - scroll up */
|
|
memmove(&data->window_text[0],
|
|
&data->window_text[1],
|
|
(MSG_LINES-1)*sizeof(data->window_text[0]));
|
|
}
|
|
|
|
/* append new text to the end of the array */
|
|
data->window_text[MSG_LINES-1].attr = msg_data->attr;
|
|
strncpy(data->window_text[MSG_LINES-1].text, msg_data->text, MAXWINDOWTEXT);
|
|
}
|
|
|
|
/* reset V-scroll position to display new text */
|
|
data->yPos = data->yMax;
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_POS;
|
|
si.nPos = data->yPos;
|
|
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
|
|
|
/* deal with overflows */
|
|
data->lines_last_turn++;
|
|
if( !data->dont_care && data->lines_last_turn>=MSG_LINES-2 ) {
|
|
char c;
|
|
BOOL done;
|
|
|
|
/* append "--More--" to the message window text (cannot call putstr
|
|
here - infinite recursion) */
|
|
memmove(&data->window_text[0],
|
|
&data->window_text[1],
|
|
(MSG_LINES-1)*sizeof(data->window_text[0]));
|
|
data->window_text[MSG_LINES-1].attr = ATR_NONE;
|
|
strncpy(data->window_text[MSG_LINES-1].text, "--More--", MAXWINDOWTEXT);
|
|
|
|
/* update window content */
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
NHSPhoneSetKeypadFromString( "\033- <>" );
|
|
#endif
|
|
|
|
done = FALSE;
|
|
while( !done ) {
|
|
int x, y, mod;
|
|
c = mswin_nh_poskey(&x, &y, &mod);
|
|
switch (c) {
|
|
/* ESC indicates that we can safely discard any further messages during this turn */
|
|
case '\033':
|
|
data->dont_care = 1;
|
|
done = TRUE;
|
|
break;
|
|
|
|
case '<':
|
|
SendMessage(hWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), (LPARAM)NULL);
|
|
break;
|
|
|
|
case '>':
|
|
SendMessage(hWnd, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM)NULL);
|
|
break;
|
|
|
|
/* continue scrolling on any key */
|
|
default:
|
|
data->lines_last_turn = 0;
|
|
done = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if defined(WIN_CE_SMARTPHONE)
|
|
NHSPhoneSetKeypadDefault();
|
|
#endif
|
|
/* remove "--More--" from the message window text */
|
|
data->window_text[MSG_LINES-1].attr = ATR_NONE;
|
|
strncpy(data->window_text[MSG_LINES-1].text, " ", MAXWINDOWTEXT);
|
|
}
|
|
|
|
/* update window content */
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
|
|
#ifdef USER_SOUNDS
|
|
play_sound_for_message(msg_data->text);
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case MSNH_MSG_CLEAR_WINDOW:
|
|
data->lines_last_turn = 0;
|
|
data->dont_care = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void onMSNH_VScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHMessageWindow data;
|
|
SCROLLINFO si;
|
|
int yInc;
|
|
|
|
/* get window data */
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_PAGE | SIF_POS;
|
|
GetScrollInfo(hWnd, SB_VERT, &si);
|
|
|
|
switch(LOWORD (wParam))
|
|
{
|
|
// User clicked the shaft above the scroll box.
|
|
|
|
case SB_PAGEUP:
|
|
yInc = -(int)si.nPage;
|
|
break;
|
|
|
|
// User clicked the shaft below the scroll box.
|
|
|
|
case SB_PAGEDOWN:
|
|
yInc = si.nPage;
|
|
break;
|
|
|
|
// User clicked the top arrow.
|
|
|
|
case SB_LINEUP:
|
|
yInc = -1;
|
|
break;
|
|
|
|
// User clicked the bottom arrow.
|
|
|
|
case SB_LINEDOWN:
|
|
yInc = 1;
|
|
break;
|
|
|
|
// User dragged the scroll box.
|
|
|
|
case SB_THUMBTRACK:
|
|
yInc = HIWORD(wParam) - data->yPos;
|
|
break;
|
|
|
|
default:
|
|
yInc = 0;
|
|
}
|
|
|
|
// If applying the vertical scrolling increment does not
|
|
// take the scrolling position out of the scrolling range,
|
|
// increment the scrolling position, adjust the position
|
|
// of the scroll box, and update the window. UpdateWindow
|
|
// sends the WM_PAINT message.
|
|
|
|
if (yInc = max( MSG_VISIBLE_LINES - data->yPos,
|
|
min(yInc, data->yMax - data->yPos)))
|
|
{
|
|
data->yPos += yInc;
|
|
/* ScrollWindowEx(hWnd, 0, -data->yChar * yInc,
|
|
(CONST RECT *) NULL, (CONST RECT *) NULL,
|
|
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE);
|
|
*/
|
|
InvalidateRect(hWnd, NULL, TRUE);
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_POS;
|
|
si.nPos = data->yPos;
|
|
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
|
|
|
|
UpdateWindow (hWnd);
|
|
}
|
|
}
|
|
|
|
#ifndef MSG_WRAP_TEXT
|
|
void onMSNH_HScroll(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PNHMessageWindow data;
|
|
SCROLLINFO si;
|
|
int xInc;
|
|
|
|
/* get window data */
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_PAGE;
|
|
GetScrollInfo(hWnd, SB_HORZ, &si);
|
|
|
|
switch(LOWORD (wParam))
|
|
{
|
|
// User clicked shaft left of the scroll box.
|
|
|
|
case SB_PAGEUP:
|
|
xInc = - (int)si.nPage;
|
|
break;
|
|
|
|
// User clicked shaft right of the scroll box.
|
|
|
|
case SB_PAGEDOWN:
|
|
xInc = si.nPage;
|
|
break;
|
|
|
|
// User clicked the left arrow.
|
|
|
|
case SB_LINEUP:
|
|
xInc = -1;
|
|
break;
|
|
|
|
// User clicked the right arrow.
|
|
|
|
case SB_LINEDOWN:
|
|
xInc = 1;
|
|
break;
|
|
|
|
// User dragged the scroll box.
|
|
|
|
case SB_THUMBTRACK:
|
|
xInc = HIWORD(wParam) - data->xPos;
|
|
break;
|
|
|
|
default:
|
|
xInc = 0;
|
|
|
|
}
|
|
|
|
|
|
// If applying the horizontal scrolling increment does not
|
|
// take the scrolling position out of the scrolling range,
|
|
// increment the scrolling position, adjust the position
|
|
// of the scroll box, and update the window.
|
|
|
|
if (xInc = max (-data->xPos, min (xInc, data->xMax - data->xPos)))
|
|
{
|
|
data->xPos += xInc;
|
|
ScrollWindowEx (hWnd, -data->xChar * xInc, 0,
|
|
(CONST RECT *) NULL, (CONST RECT *) NULL,
|
|
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE | SW_ERASE);
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cbSize = sizeof(si);
|
|
si.fMask = SIF_POS;
|
|
si.nPos = data->xPos;
|
|
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
|
|
UpdateWindow (hWnd);
|
|
}
|
|
}
|
|
#endif // MSG_WRAP_TEXT
|
|
|
|
COLORREF setMsgTextColor(HDC hdc, int gray)
|
|
{
|
|
COLORREF fg, color1, color2;
|
|
if (gray) {
|
|
color1 = mswin_get_color(NHW_MESSAGE, MSWIN_COLOR_BG);
|
|
color2 = mswin_get_color(NHW_MESSAGE, MSWIN_COLOR_FG);
|
|
/* Make a "gray" color by taking the average of the individual R,G,B
|
|
components of two colors. Thanks to Jonathan del Strother */
|
|
fg = RGB((GetRValue(color1)+GetRValue(color2))/2,
|
|
(GetGValue(color1)+GetGValue(color2))/2,
|
|
(GetBValue(color1)+GetBValue(color2))/2);
|
|
} else {
|
|
fg = mswin_get_color(NHW_MESSAGE, MSWIN_COLOR_FG);
|
|
}
|
|
|
|
return SetTextColor(hdc, fg);
|
|
}
|
|
|
|
void onPaint(HWND hWnd)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hdc;
|
|
PNHMessageWindow data;
|
|
RECT client_rt, draw_rt;
|
|
int FirstLine, LastLine;
|
|
int i, x, y;
|
|
HGDIOBJ oldFont;
|
|
TCHAR wbuf[MAXWINDOWTEXT+2];
|
|
size_t wlen;
|
|
COLORREF OldBg, OldFg;
|
|
|
|
hdc = BeginPaint(hWnd, &ps);
|
|
|
|
OldBg = SetBkColor(hdc, mswin_get_color(NHW_MESSAGE, MSWIN_COLOR_BG));
|
|
OldFg = setMsgTextColor(hdc, 0);
|
|
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
|
|
GetClientRect(hWnd, &client_rt);
|
|
|
|
if( !IsRectEmpty(&ps.rcPaint) ) {
|
|
FirstLine = max (0, data->yPos - (client_rt.bottom - ps.rcPaint.top)/data->yChar + 1);
|
|
LastLine = min (MSG_LINES-1, data->yPos - (client_rt.bottom - ps.rcPaint.bottom)/data->yChar);
|
|
y = min( ps.rcPaint.bottom, client_rt.bottom - 2);
|
|
for (i=LastLine; i>=FirstLine; i--) {
|
|
if( i==MSG_LINES-1 ) {
|
|
x = data->xChar * (2 - data->xPos);
|
|
} else {
|
|
x = data->xChar * (4 - data->xPos);
|
|
}
|
|
|
|
|
|
if( strlen(data->window_text[i].text)>0 ) {
|
|
/* convert to UNICODE */
|
|
NH_A2W(data->window_text[i].text, wbuf, sizeof(wbuf));
|
|
wlen = _tcslen(wbuf);
|
|
|
|
/* calculate text height */
|
|
draw_rt.left = x;
|
|
draw_rt.right = client_rt.right;
|
|
draw_rt.top = y - data->yChar;
|
|
draw_rt.bottom = y;
|
|
|
|
oldFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, data->window_text[i].attr, hdc, FALSE));
|
|
|
|
setMsgTextColor(hdc, i < (MSG_LINES - data->lines_last_turn));
|
|
#ifdef MSG_WRAP_TEXT
|
|
DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK | DT_CALCRECT);
|
|
draw_rt.top = y - (draw_rt.bottom - draw_rt.top);
|
|
draw_rt.bottom = y;
|
|
DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX | DT_WORDBREAK);
|
|
#else
|
|
DrawText(hdc, wbuf, wlen, &draw_rt, DT_NOPREFIX );
|
|
#endif
|
|
SelectObject(hdc, oldFont);
|
|
|
|
y -= draw_rt.bottom - draw_rt.top;
|
|
} else {
|
|
y -= data->yChar;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetTextColor (hdc, OldFg);
|
|
SetBkColor (hdc, OldBg);
|
|
EndPaint(hWnd, &ps);
|
|
}
|
|
|
|
void onCreate(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HDC hdc;
|
|
TEXTMETRIC tm;
|
|
PNHMessageWindow data;
|
|
HGDIOBJ saveFont;
|
|
|
|
/* set window data */
|
|
data = (PNHMessageWindow)malloc(sizeof(NHMessageWindow));
|
|
if( !data ) panic("out of memory");
|
|
ZeroMemory(data, sizeof(NHMessageWindow));
|
|
data->max_text = MAXWINDOWTEXT;
|
|
SetWindowLong(hWnd, GWL_USERDATA, (LONG)data);
|
|
|
|
/* Get the handle to the client area's device context. */
|
|
hdc = GetDC(hWnd);
|
|
saveFont = SelectObject(hdc, mswin_get_font(NHW_MESSAGE, ATR_NONE, hdc, FALSE));
|
|
|
|
/* Extract font dimensions from the text metrics. */
|
|
GetTextMetrics (hdc, &tm);
|
|
data->xChar = tm.tmAveCharWidth;
|
|
data->xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * data->xChar/2;
|
|
data->yChar = tm.tmHeight + tm.tmExternalLeading;
|
|
data->xPage = 1;
|
|
|
|
/* Free the device context. */
|
|
SelectObject(hdc, saveFont);
|
|
ReleaseDC (hWnd, hdc);
|
|
|
|
/* create command pad (keyboard emulator) */
|
|
if( !GetNHApp()->hCmdWnd )
|
|
GetNHApp()->hCmdWnd = mswin_init_command_window();
|
|
}
|
|
|
|
void mswin_message_window_size (HWND hWnd, LPSIZE sz)
|
|
{
|
|
PNHMessageWindow data;
|
|
RECT rt, client_rt;
|
|
|
|
GetWindowRect(hWnd, &rt);
|
|
|
|
sz->cx = rt.right - rt.left;
|
|
sz->cy = rt.bottom - rt.top;
|
|
|
|
data = (PNHMessageWindow)GetWindowLong(hWnd, GWL_USERDATA);
|
|
if(data) {
|
|
/* set size to accomodate MSG_VISIBLE_LINES, highligh rectangle and
|
|
horizontal scroll bar (difference between window rect and client rect */
|
|
GetClientRect(hWnd, &client_rt);
|
|
sz->cy = sz->cy-(client_rt.bottom - client_rt.top) +
|
|
data->yChar * MSG_VISIBLE_LINES + 4;
|
|
}
|
|
}
|
|
|