mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-28 16:17:09 +08:00
732 lines
21 KiB
C
732 lines
21 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT NOTICE
|
|
//
|
|
// The following open source license statement does not apply to any
|
|
// entity in the Exception List published by FMSoft.
|
|
//
|
|
// For more information, please visit:
|
|
//
|
|
// https://www.fmsoft.cn/exception-list
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
* This file is part of MiniGUI, a mature cross-platform windowing
|
|
* and Graphics User Interface (GUI) support system for embedded systems
|
|
* and smart IoT devices.
|
|
*
|
|
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
|
|
* Copyright (C) 1998~2002, WEI Yongming
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Or,
|
|
*
|
|
* As this program is a library, any link to this program must follow
|
|
* GNU General Public License version 3 (GPLv3). If you cannot accept
|
|
* GPLv3, you need to be licensed from FMSoft.
|
|
*
|
|
* If you have got a commercial license of this program, please use it
|
|
* under the terms and conditions of the commercial license.
|
|
*
|
|
* For more information about the commercial license, please refer to
|
|
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
|
|
*/
|
|
/*
|
|
** scrolled.c: basic scrolled window support
|
|
**
|
|
** Create date: 2004/03/01
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "common.h"
|
|
|
|
#ifdef _MGCTRL_SCROLLVIEW
|
|
#include "minigui.h"
|
|
#include "gdi.h"
|
|
#include "window.h"
|
|
#include "ctrl/ctrlhelper.h"
|
|
#include "ctrl/scrollview.h"
|
|
#include "cliprect.h"
|
|
#include "internals.h"
|
|
#include "ctrlclass.h"
|
|
|
|
#include "scrolled.h"
|
|
|
|
|
|
#define SV_H_OUTRANGE() \
|
|
(pscrdata->nContWidth > pscrdata->visibleWidth)
|
|
|
|
#define SV_V_OUTRANGE() \
|
|
(pscrdata->nContHeight > pscrdata->visibleHeight)
|
|
|
|
#define svHScroll(scrollval, newpos) \
|
|
svScroll(hWnd, pscrdata, scrollval, newpos, TRUE);
|
|
|
|
#define svVScroll(scrollval, newpos) \
|
|
svScroll (hWnd, pscrdata, scrollval, newpos, FALSE);
|
|
|
|
/* ---------------------------------------------------------------------------- */
|
|
|
|
/* adjust the horz scrollbar according to the content offset value */
|
|
int scrolled_set_hscrollinfo (HWND hWnd, PSCRDATA pscrdata)
|
|
{
|
|
SCROLLINFO si;
|
|
|
|
if (pscrdata->sbPolicy == SB_POLICY_NEVER) {
|
|
ShowScrollBar (hWnd, SB_HORZ, FALSE);
|
|
return 0;
|
|
}
|
|
else if (pscrdata->sbPolicy == SB_POLICY_AUTOMATIC) {
|
|
if (!SV_H_OUTRANGE()) {
|
|
ShowScrollBar (hWnd, SB_HORZ, FALSE);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
si.nMin = 0;
|
|
si.nMax = pscrdata->nContWidth - 1;
|
|
si.nPage = pscrdata->visibleWidth;
|
|
si.nPos = pscrdata->nContX;
|
|
|
|
SetScrollInfo (hWnd, SB_HORZ, &si, TRUE);
|
|
ShowScrollBar (hWnd, SB_HORZ, TRUE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* adjust the vert scrollbar according to the content offset value */
|
|
int scrolled_set_vscrollinfo (HWND hWnd, PSCRDATA pscrdata)
|
|
{
|
|
SCROLLINFO si;
|
|
|
|
if (pscrdata->sbPolicy == SB_POLICY_NEVER) {
|
|
ShowScrollBar (hWnd, SB_VERT, FALSE);
|
|
return 0;
|
|
}
|
|
else if (pscrdata->sbPolicy == SB_POLICY_AUTOMATIC) {
|
|
if (!SV_V_OUTRANGE()) {
|
|
ShowScrollBar (hWnd, SB_VERT, FALSE);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
si.nMin = 0;
|
|
si.nMax = pscrdata->nContHeight - 1;
|
|
si.nPage = pscrdata->visibleHeight;
|
|
si.nPos = pscrdata->nContY;
|
|
|
|
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
|
|
ShowScrollBar (hWnd, SB_VERT, TRUE);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* set content position */
|
|
BOOL scrolled_set_cont_pos (HWND hWnd, PSCRDATA pscrdata, int cont_x, int cont_y)
|
|
{
|
|
BOOL bChange = FALSE;
|
|
int cont_w, cont_h;
|
|
|
|
cont_w = pscrdata->nContWidth - pscrdata->visibleWidth;
|
|
cont_h = pscrdata->nContHeight - pscrdata->visibleHeight;
|
|
|
|
if (cont_x > cont_w && cont_w > 0)
|
|
cont_x = cont_w;
|
|
|
|
if (cont_y > cont_h && cont_h > 0)
|
|
cont_y = cont_h;
|
|
|
|
if (cont_x >= 0 && cont_x <= cont_w) {
|
|
//move content
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
pscrdata->nContX = cont_x;
|
|
scrolled_set_content (hWnd, pscrdata, FALSE);
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
SetScrollPos (hWnd, SB_HORZ, cont_x);
|
|
bChange = TRUE;
|
|
}
|
|
if (cont_y >= 0 && cont_y <= cont_h) {
|
|
//move content
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
pscrdata->nContY = cont_y;
|
|
scrolled_set_content (hWnd, pscrdata, FALSE);
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
SetScrollPos (hWnd, SB_VERT, cont_y);
|
|
bChange = TRUE;
|
|
}
|
|
|
|
if (bChange)
|
|
UpdateInvalidClient(hWnd, FALSE);
|
|
|
|
return bChange;
|
|
}
|
|
|
|
/* make a point in the content area visible */
|
|
BOOL scrolled_make_pos_visible (HWND hWnd, PSCRDATA pscrdata, int pos_x, int pos_y)
|
|
{
|
|
int cont_x = -1, cont_y = -1;
|
|
|
|
if (pos_x >= 0) {
|
|
if (pos_x >= pscrdata->nContWidth)
|
|
pos_x = pscrdata->nContWidth - 1;
|
|
if (pos_x < pscrdata->nContX)
|
|
cont_x = pos_x;
|
|
else if (pos_x > pscrdata->nContX + pscrdata->visibleWidth - 1)
|
|
cont_x = pos_x - pscrdata->visibleWidth + 1;
|
|
}
|
|
if (pos_y >= 0) {
|
|
if (pos_y >= pscrdata->nContHeight)
|
|
pos_y = pscrdata->nContHeight - 1;
|
|
if (pos_y < pscrdata->nContY)
|
|
cont_y = pos_y;
|
|
else if (pos_y > pscrdata->nContY + pscrdata->visibleHeight - 1)
|
|
cont_y = pos_y - pscrdata->visibleHeight + 1;
|
|
}
|
|
return scrolled_set_cont_pos (hWnd, pscrdata, cont_x, cont_y);
|
|
}
|
|
|
|
/* scrollbar action */
|
|
static void svScroll (HWND hWnd, PSCRDATA pscrdata, int scrollval, int newpos, BOOL bHScroll)
|
|
{
|
|
int scrollBoundMax;
|
|
int scrollBoundMin;
|
|
int scroll = 0;
|
|
BOOL bScroll = FALSE;
|
|
int nOffset;
|
|
|
|
if (bHScroll) {
|
|
scrollBoundMax = pscrdata->nContWidth - pscrdata->visibleWidth;
|
|
nOffset = pscrdata->nContX;
|
|
}
|
|
else {
|
|
scrollBoundMax = pscrdata->nContHeight - pscrdata->visibleHeight;
|
|
nOffset = pscrdata->nContY;
|
|
}
|
|
scrollBoundMin = 0;
|
|
|
|
if (newpos >= 0) { // SB_THUMBTRACK
|
|
scrollval = newpos - nOffset;
|
|
}
|
|
|
|
scroll = (scrollval>0?scrollval:-scrollval);
|
|
|
|
if (scrollval > 0 && nOffset < scrollBoundMax) {
|
|
if ((nOffset + scroll) > scrollBoundMax)
|
|
nOffset = scrollBoundMax;
|
|
else
|
|
nOffset += scroll;
|
|
bScroll = TRUE;
|
|
}
|
|
else if ( scrollval < 0 && nOffset > scrollBoundMin) {
|
|
if ((nOffset - scroll) < scrollBoundMin)
|
|
nOffset = scrollBoundMin;
|
|
else
|
|
nOffset -= scroll;
|
|
bScroll = TRUE;
|
|
}
|
|
if (bScroll) {
|
|
scrolled_set_cont_pos (hWnd, pscrdata, (bHScroll?nOffset:-1), (bHScroll?-1:nOffset));
|
|
}
|
|
}
|
|
|
|
/* set the position and size of the viewport window */
|
|
void scrolled_set_visible (HWND hWnd, PSCRDATA pscrdata)
|
|
{
|
|
/* maybe we need to reset content width and height */
|
|
if (pscrdata->nContWidth < pscrdata->visibleWidth) {
|
|
/* houhh 20101012, do not need to reset nContWidth here, Because the content
|
|
* width should be modify by add content.*/
|
|
#if 0
|
|
pscrdata->nContWidth = pscrdata->visibleWidth;
|
|
#endif
|
|
pscrdata->nContX = 0;
|
|
pscrdata->prevnContX = 0;
|
|
}
|
|
else {
|
|
if(pscrdata->nContX > pscrdata->nContWidth - pscrdata->visibleWidth
|
|
&&(pscrdata->nContWidth - pscrdata->visibleWidth) > 0 ) {
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
pscrdata->nContX = pscrdata->nContWidth - pscrdata->visibleWidth;
|
|
}
|
|
}
|
|
|
|
if (pscrdata->nContHeight < pscrdata->visibleHeight) {
|
|
#if 0
|
|
pscrdata->nContHeight = pscrdata->visibleHeight;
|
|
#endif
|
|
pscrdata->nContY = 0;
|
|
pscrdata->prevnContY = 0;
|
|
}
|
|
else{
|
|
if(pscrdata->nContY > pscrdata->nContHeight - pscrdata->visibleHeight
|
|
&& (pscrdata->nContHeight - pscrdata->visibleHeight) > 0) {
|
|
pscrdata->nContY = pscrdata->nContHeight - pscrdata->visibleHeight;
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
}
|
|
}
|
|
/* refresh the whole window as long as the visible area is changed */
|
|
scrolled_set_content (hWnd, pscrdata, TRUE);
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
}
|
|
|
|
int scrolled_visible_to_content (PSCRDATA pscrdata, int *x, int *y)
|
|
{
|
|
if (x)
|
|
*x = *x + pscrdata->nContX;
|
|
if (y)
|
|
*y = *y + pscrdata->nContY;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int scrolled_content_to_visible (PSCRDATA pscrdata, int *x, int *y)
|
|
{
|
|
if (x)
|
|
*x = *x - pscrdata->nContX;
|
|
|
|
if (y)
|
|
*y = *y - pscrdata->nContY;
|
|
|
|
if (!x || !y)
|
|
return -1;
|
|
|
|
if (*x < 0 || *x > pscrdata->visibleWidth ||
|
|
*y < 0 || *y > pscrdata->visibleHeight)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
/* recalc visible area and container area, then set scrollbar */
|
|
void scrolled_recalc_areas (HWND hWnd, PSCRDATA pscrdata, int new_w, int new_h)
|
|
{
|
|
if (!pscrdata || new_w <= 0 || new_h <= 0)
|
|
return;
|
|
|
|
/* reset viewport as client - margin */
|
|
pscrdata->visibleWidth = new_w;
|
|
pscrdata->visibleHeight = new_h;
|
|
scrolled_set_visible (hWnd, pscrdata);
|
|
|
|
/*
|
|
int old_vw, old_vh;
|
|
|
|
old_vw = pscrdata->visibleWidth;
|
|
old_vh = pscrdata->visibleHeight;
|
|
|
|
if (pscrdata->nContWidth == old_vw) {
|
|
pscrdata->nContWidth = pscrdata->visibleWidth;
|
|
//should refresh the whole window
|
|
scrolled_set_content (hWnd, pscrdata, TRUE);
|
|
}
|
|
if (pscrdata->nContHeight == old_vh) {
|
|
pscrdata->nContHeight = pscrdata->visibleHeight;
|
|
//should refresh the whole window
|
|
scrolled_set_content (hWnd, pscrdata, TRUE);
|
|
}
|
|
*/
|
|
scrolled_set_hscrollinfo (hWnd, pscrdata);
|
|
scrolled_set_vscrollinfo (hWnd, pscrdata);
|
|
}
|
|
|
|
void scrolled_hscroll (HWND hWnd, PSCRDATA pscrdata, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int hscroll = 0, newpos = -1;
|
|
|
|
if (wParam == SB_LINERIGHT)
|
|
hscroll = pscrdata->hScrollVal;
|
|
else if (wParam == SB_LINELEFT)
|
|
hscroll = -pscrdata->hScrollVal;
|
|
else if (wParam == SB_PAGERIGHT)
|
|
hscroll = pscrdata->hScrollPageVal;
|
|
else if (wParam == SB_PAGELEFT)
|
|
hscroll = -pscrdata->hScrollPageVal;
|
|
else if (wParam == SB_THUMBTRACK)
|
|
newpos = lParam;
|
|
else if (wParam == SB_THUMBPOSITION) {
|
|
newpos = lParam;
|
|
}
|
|
|
|
svHScroll (hscroll, newpos);
|
|
}
|
|
|
|
void scrolled_vscroll (HWND hWnd, PSCRDATA pscrdata, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int vscroll = 0, newpos = -1;
|
|
|
|
if (wParam == SB_LINEDOWN)
|
|
vscroll = pscrdata->vScrollVal;
|
|
else if (wParam == SB_LINEUP)
|
|
vscroll = -pscrdata->vScrollVal;
|
|
else if (wParam == SB_PAGEDOWN)
|
|
vscroll = pscrdata->vScrollPageVal;
|
|
else if (wParam == SB_PAGEUP)
|
|
vscroll = -pscrdata->vScrollPageVal;
|
|
else if (wParam == SB_THUMBTRACK) {
|
|
newpos = lParam;
|
|
}
|
|
else if (wParam == SB_THUMBPOSITION) {
|
|
newpos = lParam;
|
|
}
|
|
|
|
if (wParam != SB_THUMBPOSITION)
|
|
svVScroll (vscroll, newpos);
|
|
}
|
|
|
|
int scrolled_set_cont_width (HWND hWnd, PSCRDATA pscrdata, int cont_w)
|
|
{
|
|
int oldval = pscrdata->nContWidth;
|
|
|
|
if (cont_w < 0)
|
|
return 0;
|
|
//pscrdata->nContWidth = cont_w < pscrdata->visibleWidth ? pscrdata->visibleWidth : cont_w;
|
|
pscrdata->nContWidth = cont_w;
|
|
|
|
if (pscrdata->nContWidth == oldval)
|
|
return 0;
|
|
|
|
if (pscrdata->nContX > pscrdata->nContWidth - pscrdata->visibleWidth
|
|
&& (pscrdata->nContWidth - pscrdata->visibleWidth) > 0) {
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
pscrdata->nContX = pscrdata->nContWidth - pscrdata->visibleWidth;
|
|
}
|
|
else if(pscrdata->nContWidth <= pscrdata->visibleWidth) {
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
pscrdata->nContX = 0;
|
|
}
|
|
|
|
scrolled_set_hscrollinfo (hWnd, pscrdata);
|
|
//move content
|
|
scrolled_set_content (hWnd, pscrdata, FALSE);
|
|
pscrdata->prevnContX = pscrdata->nContX;
|
|
|
|
return pscrdata->nContWidth;
|
|
}
|
|
|
|
int scrolled_set_cont_height (HWND hWnd, PSCRDATA pscrdata, int cont_h)
|
|
{
|
|
int oldval = pscrdata->nContHeight;
|
|
|
|
if (cont_h < 0)
|
|
return 0;
|
|
|
|
//pscrdata->nContHeight = cont_h < pscrdata->visibleHeight ? pscrdata->visibleHeight : cont_h;
|
|
pscrdata->nContHeight = cont_h;
|
|
if (pscrdata->nContHeight == oldval)
|
|
return 0;
|
|
|
|
if (pscrdata->nContY > pscrdata->nContHeight - pscrdata->visibleHeight
|
|
&& (pscrdata->nContHeight - pscrdata->visibleHeight) > 0) {
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
pscrdata->nContY = pscrdata->nContHeight - pscrdata->visibleHeight;
|
|
}
|
|
else if (pscrdata->nContHeight <= pscrdata->visibleHeight) {
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
pscrdata->nContY = 0;
|
|
}
|
|
|
|
scrolled_set_vscrollinfo (hWnd, pscrdata);
|
|
//move content
|
|
scrolled_set_content (hWnd, pscrdata, FALSE);
|
|
pscrdata->prevnContY = pscrdata->nContY;
|
|
|
|
return pscrdata->nContHeight;
|
|
}
|
|
|
|
/*
|
|
int scrolled_SetVisibleWidth (HWND hWnd, PSCRDATA pscrdata, int vis_w)
|
|
{
|
|
int oldval = pscrdata->visibleWidth;
|
|
|
|
if (vis_w < 0)
|
|
return 0;
|
|
|
|
pscrdata->visibleWidth = vis_w < pscrdata->nContWidth ? vis_w : pscrdata->nContWidth;
|
|
if (pscrdata->visibleWidth = oldval)
|
|
return 0;
|
|
|
|
scrolled_set_hscrollinfo (hWnd, pscrdata);
|
|
|
|
return pscrdata->visibleWidth;
|
|
}
|
|
*/
|
|
|
|
void scrolled_set_scrollval (PSCRDATA pscrdata, int hval, int vval)
|
|
{
|
|
if (hval > 0)
|
|
pscrdata->hScrollVal = hval;
|
|
if (vval > 0)
|
|
pscrdata->vScrollVal = vval;
|
|
}
|
|
|
|
void scrolled_set_scrollpageval (PSCRDATA pscrdata, int hval, int vval)
|
|
{
|
|
if (hval > 0)
|
|
pscrdata->hScrollPageVal = hval;
|
|
if (vval > 0)
|
|
pscrdata->vScrollPageVal = vval;
|
|
}
|
|
|
|
void scrolled_set_margins (PSCRDATA pscrdata, RECT *rc)
|
|
{
|
|
RECT rcWnd;
|
|
|
|
if (!rc)
|
|
return;
|
|
|
|
if (rc->left >= 0)
|
|
pscrdata->leftMargin = rc->left;
|
|
if (rc->right >= 0)
|
|
pscrdata->rightMargin = rc->right;
|
|
if (rc->top >= 0)
|
|
pscrdata->topMargin = rc->top;
|
|
if (rc->bottom >= 0)
|
|
pscrdata->bottomMargin = rc->bottom;
|
|
|
|
GetClientRect (pscrdata->hSV, &rcWnd);
|
|
scrolled_recalc_areas (pscrdata->hSV, pscrdata,
|
|
RECTW(rcWnd) - pscrdata->leftMargin - pscrdata->rightMargin,
|
|
RECTH(rcWnd) - pscrdata->topMargin - pscrdata->bottomMargin);
|
|
}
|
|
|
|
void scrolled_refresh_rect (PSCRDATA pscrdata, RECT *rc)
|
|
{
|
|
RECT rcUpdate;
|
|
|
|
memcpy (&rcUpdate, rc, sizeof(RECT));
|
|
|
|
scrolled_content_to_window (pscrdata, NULL, &rcUpdate.top);
|
|
rcUpdate.bottom = rcUpdate.top + RECTHP(rc);
|
|
|
|
if (rcUpdate.right == 0) {
|
|
rcUpdate.left = 0;
|
|
scrolled_content_to_window (pscrdata, &rcUpdate.left, NULL);
|
|
if (rcUpdate.left < 0)
|
|
rcUpdate.right = rcUpdate.left + pscrdata->nContWidth;
|
|
else
|
|
rcUpdate.right = rcUpdate.left + pscrdata->visibleWidth;
|
|
}
|
|
|
|
InvalidateRect ( pscrdata->hSV, &rcUpdate, TRUE);
|
|
}
|
|
|
|
void scrolled_init_contsize (HWND hWnd, PSCRDATA pscrdata)
|
|
{
|
|
pscrdata->nContX = 0;
|
|
pscrdata->nContY = 0;
|
|
pscrdata->prevnContX = 0;
|
|
pscrdata->prevnContY = 0;
|
|
|
|
pscrdata->nContWidth = pscrdata->visibleWidth;
|
|
pscrdata->nContHeight = pscrdata->visibleHeight;
|
|
}
|
|
|
|
void scrolled_init_margins (PSCRDATA pscrdata, int left, int top,
|
|
int right, int bottom)
|
|
{
|
|
pscrdata->leftMargin = left;
|
|
pscrdata->topMargin = top;
|
|
pscrdata->rightMargin = right;
|
|
pscrdata->bottomMargin = bottom;
|
|
}
|
|
|
|
/* set initial content size and viewport size */
|
|
int scrolled_init (HWND hWnd, PSCRDATA pscrdata, int w, int h)
|
|
{
|
|
RECT rcWnd;
|
|
|
|
/* new added */
|
|
pscrdata->leftMargin = 0;
|
|
pscrdata->topMargin = 0;
|
|
pscrdata->rightMargin = 0;
|
|
pscrdata->bottomMargin = 0;
|
|
|
|
pscrdata->nContX = 0;
|
|
pscrdata->nContY = 0;
|
|
pscrdata->prevnContX = 0;
|
|
pscrdata->prevnContY = 0;
|
|
|
|
if (w > 0 && h > 0) {
|
|
pscrdata->visibleWidth = w;
|
|
pscrdata->visibleHeight = h;
|
|
}
|
|
else {
|
|
GetClientRect (hWnd, &rcWnd);
|
|
pscrdata->visibleWidth = RECTW(rcWnd);
|
|
pscrdata->visibleHeight = RECTH(rcWnd);
|
|
}
|
|
|
|
pscrdata->nContWidth = pscrdata->visibleWidth;
|
|
pscrdata->nContHeight = pscrdata->visibleHeight;
|
|
|
|
pscrdata->sbPolicy = SB_POLICY_AUTOMATIC;
|
|
|
|
pscrdata->hScrollVal = HSCROLL;
|
|
pscrdata->vScrollVal = VSCROLL;
|
|
pscrdata->hScrollPageVal = pscrdata->visibleWidth;
|
|
pscrdata->vScrollPageVal = pscrdata->visibleHeight;
|
|
|
|
pscrdata->hSV = hWnd;
|
|
|
|
return 0;
|
|
}
|
|
|
|
LRESULT DefaultScrolledProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PSCRDATA pscrdata = NULL;
|
|
|
|
if (message != MSG_CREATE)
|
|
pscrdata = (PSCRDATA) GetWindowAdditionalData2 (hWnd);
|
|
|
|
switch (message) {
|
|
|
|
case MSG_HSCROLL:
|
|
scrolled_hscroll (hWnd, pscrdata, wParam, lParam);
|
|
break;
|
|
|
|
case MSG_VSCROLL:
|
|
scrolled_vscroll (hWnd, pscrdata, wParam, lParam);
|
|
break;
|
|
|
|
/*
|
|
* three cases:
|
|
* 1. move window; 2. set content range; 3. show scrollbar
|
|
*/
|
|
case MSG_SIZECHANGED:
|
|
{
|
|
RECT *rcClient = (RECT*)lParam;
|
|
|
|
//default case : the whole client area is the visible area
|
|
//scrollwnd control is this case
|
|
//scrollview control is different
|
|
|
|
if (!pscrdata)
|
|
return 0;
|
|
|
|
//scrolled_recalc_areas (hWnd, pscrdata, RECTWP(rcClient), RECTHP(rcClient));
|
|
scrolled_recalc_areas (hWnd, pscrdata,
|
|
RECTWP(rcClient) - pscrdata->leftMargin - pscrdata->rightMargin,
|
|
RECTHP(rcClient) - pscrdata->topMargin - pscrdata->bottomMargin);
|
|
return 0;
|
|
}
|
|
|
|
case MSG_KEYDOWN:
|
|
{
|
|
if (wParam == SCANCODE_PAGEDOWN) {
|
|
SendMessage (hWnd, MSG_VSCROLL, SB_PAGEDOWN, 0);
|
|
}
|
|
else if (wParam == SCANCODE_PAGEUP)
|
|
SendMessage (hWnd, MSG_VSCROLL, SB_PAGEUP, 0);
|
|
else if (wParam == SCANCODE_CURSORBLOCKLEFT)
|
|
SendMessage (hWnd, MSG_HSCROLL, SB_PAGELEFT, 0);
|
|
else if (wParam == SCANCODE_CURSORBLOCKRIGHT)
|
|
SendMessage (hWnd, MSG_HSCROLL, SB_PAGERIGHT, 0);
|
|
break;
|
|
}
|
|
|
|
case SVM_SETCONTRANGE:
|
|
scrolled_set_cont_width (hWnd, pscrdata, wParam);
|
|
scrolled_set_cont_height (hWnd, pscrdata, lParam);
|
|
return 0;
|
|
|
|
case SVM_SETCONTWIDTH:
|
|
return scrolled_set_cont_width (hWnd, pscrdata, wParam);
|
|
|
|
case SVM_SETCONTHEIGHT:
|
|
return scrolled_set_cont_height (hWnd, pscrdata, wParam);
|
|
|
|
case SVM_GETHSCROLLVAL:
|
|
return pscrdata->hScrollVal;
|
|
case SVM_GETVSCROLLVAL:
|
|
return pscrdata->vScrollVal;
|
|
case SVM_GETHSCROLLPAGEVAL:
|
|
return pscrdata->hScrollPageVal;
|
|
case SVM_GETVSCROLLPAGEVAL:
|
|
return pscrdata->vScrollPageVal;
|
|
|
|
case SVM_SETSCROLLVAL:
|
|
{
|
|
scrolled_set_scrollval (pscrdata, wParam, lParam);
|
|
return 0;
|
|
}
|
|
case SVM_SETSCROLLPAGEVAL:
|
|
{
|
|
scrolled_set_scrollpageval (pscrdata, wParam, lParam);
|
|
return 0;
|
|
}
|
|
|
|
case SVM_SETCONTPOS:
|
|
{
|
|
scrolled_set_cont_pos (hWnd, pscrdata, wParam, lParam);
|
|
return 0;
|
|
}
|
|
|
|
/* get scrolled size information */
|
|
case SVM_GETCONTWIDTH:
|
|
return pscrdata->nContWidth;
|
|
case SVM_GETCONTHEIGHT:
|
|
return pscrdata->nContHeight;
|
|
case SVM_GETCONTENTX:
|
|
return pscrdata->nContX;
|
|
case SVM_GETCONTENTY:
|
|
return pscrdata->nContY;
|
|
case SVM_GETVISIBLEWIDTH:
|
|
return pscrdata->visibleWidth;
|
|
case SVM_GETVISIBLEHEIGHT:
|
|
return pscrdata->visibleHeight;
|
|
|
|
case SVM_GETMARGINS:
|
|
{
|
|
RECT *rc = (RECT *)lParam;
|
|
if (rc)
|
|
scrolled_get_margins (pscrdata, rc);
|
|
return 0;
|
|
}
|
|
|
|
case SVM_GETLEFTMARGIN:
|
|
return pscrdata->leftMargin;
|
|
case SVM_GETRIGHTMARGIN:
|
|
return pscrdata->rightMargin;
|
|
case SVM_GETTOPMARGIN:
|
|
return pscrdata->topMargin;
|
|
case SVM_GETBOTTOMMARGIN:
|
|
return pscrdata->bottomMargin;
|
|
|
|
case SVM_SETMARGINS:
|
|
{
|
|
RECT *rc = (RECT *)lParam;
|
|
if (rc)
|
|
scrolled_set_margins (pscrdata, rc);
|
|
return 0;
|
|
}
|
|
|
|
case SVM_MAKEPOSVISIBLE:
|
|
scrolled_make_pos_visible (hWnd, pscrdata, wParam, lParam);
|
|
return 0;
|
|
|
|
}/* end switch */
|
|
|
|
return DefaultControlProc (hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
|
|
#endif /* _MGCTRL_SCROLLVIEW */
|