?? tkwinscrlbr.c
字號:
/* * tkWinScrollbar.c -- * * This file implements the Windows specific portion of the scrollbar * widget. * * Copyright (c) 1996 by Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkWinScrlbr.c 1.19 97/08/13 17:37:49 */#include "tkWinInt.h"#include "tkScrollbar.h"/* * The following constant is used to specify the maximum scroll position. * This value is limited by the Win32 API to either 16-bits or 32-bits, * depending on the context. For now we'll just use a value small * enough to fit in 16-bits, but which gives us 4-digits of precision. */#define MAX_SCROLL 10000/* * Declaration of Windows specific scrollbar structure. */typedef struct WinScrollbar { TkScrollbar info; /* Generic scrollbar info. */ WNDPROC oldProc; /* Old window procedure. */ int lastVertical; /* 1 if was vertical at last refresh. */ HWND hwnd; /* Current window handle. */ int winFlags; /* Various flags; see below. */} WinScrollbar;/* * Flag bits for native scrollbars: * * IN_MODAL_LOOP: Non-zero means this scrollbar is in the middle * of a modal loop. * ALREADY_DEAD: Non-zero means this scrollbar has been * destroyed, but has not been cleaned up. */#define IN_MODAL_LOOP 1#define ALREADY_DEAD 2/* * Cached system metrics used to determine scrollbar geometry. */static int initialized = 0;static int hArrowWidth, hThumb; /* Horizontal control metrics. */static int vArrowWidth, vArrowHeight, vThumb; /* Vertical control metrics. *//* * This variable holds the default width for a scrollbar in string * form for use in a Tk_ConfigSpec. */static char defWidth[8];/* * Declarations for functions defined in this file. */static Window CreateProc _ANSI_ARGS_((Tk_Window tkwin, Window parent, ClientData instanceData));static void ModalLoopProc _ANSI_ARGS_((Tk_Window tkwin, XEvent *eventPtr));static int ScrollbarBindProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, XEvent *eventPtr, Tk_Window tkwin, KeySym keySym));static LRESULT CALLBACK ScrollbarProc _ANSI_ARGS_((HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam));static void UpdateScrollbar _ANSI_ARGS_(( WinScrollbar *scrollPtr));static void UpdateScrollbarMetrics _ANSI_ARGS_((void));/* * The class procedure table for the scrollbar widget. */TkClassProcs tkpScrollbarProcs = { CreateProc, /* createProc */ NULL, /* geometryProc */ ModalLoopProc, /* modalProc */};/* *---------------------------------------------------------------------- * * TkpCreateScrollbar -- * * Allocate a new TkScrollbar structure. * * Results: * Returns a newly allocated TkScrollbar structure. * * Side effects: * Registers an event handler for the widget. * *---------------------------------------------------------------------- */TkScrollbar *TkpCreateScrollbar(tkwin) Tk_Window tkwin;{ WinScrollbar *scrollPtr; TkWindow *winPtr = (TkWindow *)tkwin; if (!initialized) { UpdateScrollbarMetrics(); initialized = 1; } scrollPtr = (WinScrollbar *) ckalloc(sizeof(WinScrollbar)); scrollPtr->winFlags = 0; scrollPtr->hwnd = NULL; Tk_CreateEventHandler(tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, TkScrollbarEventProc, (ClientData) scrollPtr); if (!Tcl_GetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL)) { Tcl_SetAssocData(winPtr->mainPtr->interp, "TkScrollbar", NULL, (ClientData)1); TkCreateBindingProcedure(winPtr->mainPtr->interp, winPtr->mainPtr->bindingTable, (ClientData)Tk_GetUid("Scrollbar"), "<ButtonPress>", ScrollbarBindProc, NULL, NULL); } return (TkScrollbar*) scrollPtr;}/* *---------------------------------------------------------------------- * * UpdateScrollbar -- * * This function updates the position and size of the scrollbar * thumb based on the current settings. * * Results: * None. * * Side effects: * Moves the thumb. * *---------------------------------------------------------------------- */static voidUpdateScrollbar(scrollPtr) WinScrollbar *scrollPtr;{ SCROLLINFO scrollInfo; double thumbSize; /* * Update the current scrollbar position and shape. */ scrollInfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; scrollInfo.cbSize = sizeof(scrollInfo); scrollInfo.nMin = 0; scrollInfo.nMax = MAX_SCROLL; thumbSize = (scrollPtr->info.lastFraction - scrollPtr->info.firstFraction); if (tkpIsWin32s) { scrollInfo.nPage = 0; } else { scrollInfo.nPage = ((UINT) (thumbSize * (double) MAX_SCROLL)) + 1; } if (thumbSize < 1.0) { scrollInfo.nPos = (int) ((scrollPtr->info.firstFraction / (1.0-thumbSize)) * (MAX_SCROLL - (scrollInfo.nPage - 1))); } else { scrollInfo.nPos = 0; } SetScrollInfo(scrollPtr->hwnd, SB_CTL, &scrollInfo, TRUE);}/* *---------------------------------------------------------------------- * * CreateProc -- * * This function creates a new Scrollbar control, subclasses * the instance, and generates a new Window object. * * Results: * Returns the newly allocated Window object, or None on failure. * * Side effects: * Causes a new Scrollbar control to come into existence. * *---------------------------------------------------------------------- */static WindowCreateProc(tkwin, parentWin, instanceData) Tk_Window tkwin; /* Token for window. */ Window parentWin; /* Parent of new window. */ ClientData instanceData; /* Scrollbar instance data. */{ DWORD style; Window window; HWND parent; TkWindow *winPtr; WinScrollbar *scrollPtr = (WinScrollbar *)instanceData; parent = Tk_GetHWND(parentWin); if (scrollPtr->info.vertical) { style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBS_VERT | SBS_RIGHTALIGN; } else { style = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBS_HORZ | SBS_BOTTOMALIGN; } scrollPtr->hwnd = CreateWindow("SCROLLBAR", NULL, style, Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), parent, NULL, Tk_GetHINSTANCE(), NULL); /* * Ensure new window is inserted into the stacking order at the correct * place. */ SetWindowPos(scrollPtr->hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); for (winPtr = ((TkWindow*)tkwin)->nextPtr; winPtr != NULL; winPtr = winPtr->nextPtr) { if ((winPtr->window != None) && !(winPtr->flags & TK_TOP_LEVEL)) { TkWinSetWindowPos(scrollPtr->hwnd, Tk_GetHWND(winPtr->window), Below); break; } } scrollPtr->lastVertical = scrollPtr->info.vertical; scrollPtr->oldProc = (WNDPROC)SetWindowLong(scrollPtr->hwnd, GWL_WNDPROC, (DWORD) ScrollbarProc); window = Tk_AttachHWND(tkwin, scrollPtr->hwnd); UpdateScrollbar(scrollPtr); return window;}/* *-------------------------------------------------------------- * * TkpDisplayScrollbar -- * * This procedure redraws the contents of a scrollbar window. * It is invoked as a do-when-idle handler, so it only runs * when there's nothing else for the application to do. * * Results: * None. * * Side effects: * Information appears on the screen. * *-------------------------------------------------------------- */voidTkpDisplayScrollbar(clientData) ClientData clientData; /* Information about window. */{ WinScrollbar *scrollPtr = (WinScrollbar *) clientData; Tk_Window tkwin = scrollPtr->info.tkwin; scrollPtr->info.flags &= ~REDRAW_PENDING; if ((tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; } /* * Destroy and recreate the scrollbar control if the orientation * has changed. */ if (scrollPtr->lastVertical != scrollPtr->info.vertical) { HWND hwnd = Tk_GetHWND(Tk_WindowId(tkwin)); SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) scrollPtr->oldProc); DestroyWindow(hwnd); CreateProc(tkwin, Tk_WindowId(Tk_Parent(tkwin)), (ClientData) scrollPtr); } else { UpdateScrollbar(scrollPtr); }}/* *---------------------------------------------------------------------- * * TkpDestroyScrollbar -- * * Free data structures associated with the scrollbar control. * * Results: * None. * * Side effects: * Restores the default control state. * *---------------------------------------------------------------------- */voidTkpDestroyScrollbar(scrollPtr) TkScrollbar *scrollPtr;{ WinScrollbar *winScrollPtr = (WinScrollbar *)scrollPtr; HWND hwnd = winScrollPtr->hwnd; if (hwnd) { SetWindowLong(hwnd, GWL_WNDPROC, (DWORD) winScrollPtr->oldProc); if (winScrollPtr->winFlags & IN_MODAL_LOOP) { ((TkWindow *)scrollPtr->tkwin)->flags |= TK_DONT_DESTROY_WINDOW; SetParent(hwnd, NULL); } } winScrollPtr->winFlags |= ALREADY_DEAD;}/* *---------------------------------------------------------------------- * * UpdateScrollbarMetrics -- * * This function retrieves the current system metrics for a * scrollbar. * * Results: * None. * * Side effects: * Updates the geometry cache info for all scrollbars. * *---------------------------------------------------------------------- */voidUpdateScrollbarMetrics(){ Tk_ConfigSpec *specPtr; hArrowWidth = GetSystemMetrics(SM_CXHSCROLL); hThumb = GetSystemMetrics(SM_CXHTHUMB); vArrowWidth = GetSystemMetrics(SM_CXVSCROLL); vArrowHeight = GetSystemMetrics(SM_CYVSCROLL); vThumb = GetSystemMetrics(SM_CYVTHUMB); sprintf(defWidth, "%d", vArrowWidth); for (specPtr = tkpScrollbarConfigSpecs; specPtr->type != TK_CONFIG_END; specPtr++) { if (specPtr->offset == Tk_Offset(TkScrollbar, width)) { specPtr->defValue = defWidth; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -