📄 ccsplitter.c
字号:
/*
* Module : CCsplitter.c
* Copyright: R.W.G. H黱en (rhunen@xs4all.nl)
*
* Based on original code by Rob Pitt.
*
* This file is part of the Splitter Control.
*
* The Splitter Control 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 2 of the License, or (at your option) any
* later version.
*
* The Splitter Control 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
* the Splitter Control; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Log: $
*/
/********************************************************************************/
/* Include files */
/********************************************************************************/
#include "CCsplitter.h"
#include "resource.h"
/********************************************************************************/
/* Constant definitions */
/********************************************************************************/
#define GWL_SPINFO 0 // GetWindowLong offset of SPINFO ptr
#define NVIEWS 4 // Number of View windows
/********************************************************************************/
/* Macro definitions */
/********************************************************************************/
#define SPLT(pos,w) ((pos) - (w)/2 + 1)
#define SPRB(pos,w) ((pos) - (w)/2 + 1 + (w))
#define SPLEFT SPLT
#define SPTOP SPLT
#define SPRIGHT SPRB
#define SPBOTTOM SPRB
#define CURSORPOS_OK(cur,spl,w) ((spl)>=0 && (cur)>=SPLT(spl,w) && (cur)<=SPRB(spl,w))
/********************************************************************************/
/* Type definitions */
/********************************************************************************/
typedef struct spinfo SPINFO; // Splitter info
struct spinfo {
HWND hView[NVIEWS]; // View window handles
int xpos; // X-position of split (-1 = no split)
int ypos; // Y-position of split (-1 = no split)
int xwidth; // X-width of split bar
int ywidth; // Y-width of split bar
int xlower; // X-lower drag margin
int xupper; // X-upper drag margin
int ylower; // Y-lower drag margin
int yupper; // Y-upper drag margin high
int xdrag; // X-position during drag (-1 = no drag)
int ydrag; // Y-position during drag (-1 = no drag)
int dragDone; // Drag operation completed flag
};
/********************************************************************************/
/* Function prototypes */
/********************************************************************************/
static LRESULT CALLBACK SpWindowProc (
HWND hSplitter, // Splitter handle
UINT uMsg, // Message code
WPARAM wParam, // Message parameter
LPARAM lParam // Message parameter
);
static int SpGetRect (
HWND hSplitter, // Splitter window handle
int id, // Rectangle ID
RECT *prc // Rectangle data ptr
);
static void SpNotifyParent (
HWND hSplitter, // Splitter window handle
int code, // Notification code
int xParam, // X-parameter to notification
int yParam // Y-parameter to notification
);
static void SpPositionViewWindows (
HWND hSplitter // Splitter window handle
);
void CreateTreeView (HWND hParent); // Parent window handle
HWND hWndTreeView;
/********************************************************************************/
/* Private date definitions */
/********************************************************************************/
static HCURSOR hcurVert; // Cursor for North/South split
static HCURSOR hcurHorz; // Cursor for East/West split
static HCURSOR hcurBoth; // Cursor for double split
static HBRUSH hbrDotty; // Dotty brush handle
static WORD dottyData[] = {
0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA
};
/********************************************************************************/
/* Public procedure definitions */
/********************************************************************************/
BOOL InitCCsplitter ()
{
WNDCLASSEX wc; // Window class data
HBITMAP hbm; // Bitmap handle
if (GetClassInfoEx (GetModuleHandle (0), WC_CCSPLITTER, &wc))
return TRUE;
hcurVert = LoadCursor (NULL, IDC_SIZENS);
hcurHorz = LoadCursor (NULL, IDC_SIZEWE);
hcurBoth = LoadCursor (NULL, IDC_SIZEALL);
hbm = CreateBitmap (8, 8, 1, 1, dottyData);
hbrDotty = CreatePatternBrush (hbm);
DeleteObject (hbm);
ZeroMemory (&wc, sizeof(wc));
wc.cbSize = sizeof (wc);
wc.cbWndExtra = sizeof (SPINFO *);
wc.hInstance = GetModuleHandle (0);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush (COLOR_ACTIVEBORDER);
wc.lpfnWndProc = SpWindowProc;
wc.lpszClassName = WC_CCSPLITTER;
return RegisterClassEx (&wc) ? TRUE : FALSE;
}
/********************************************************************************/
/* Private procedure definitions - window procedure */
/********************************************************************************/
static LRESULT CALLBACK SpWindowProc (
HWND hSplitter, // Splitter window handle
UINT uMsg, // Message code
WPARAM wParam, // Message parameter
LPARAM lParam) // Message parameter
{
CCSPLIT *spx; // X-split data ptr
CCSPLIT *spy; // Y-split data ptr
SPINFO *sp; // Splitter info
RECT rc; // Window rectangle
HDC hdc; // Device Context handle
HBRUSH hbr; // Brush handle
POINT pt; // Coordinate of point
DWORD dw; // Double word temp
sp = (SPINFO *)GetWindowLong (hSplitter, GWL_SPINFO);
switch (uMsg) {
case WM_CAPTURECHANGED:
if (sp->xdrag >= 0 || sp->ydrag >= 0) {
GetClientRect (hSplitter, &rc);
hdc = GetDCEx (hSplitter, NULL, DCX_PARENTCLIP);
hbr = SelectObject (hdc, hbrDotty);
if (sp->ydrag >= 0) {
PatBlt (hdc, 0, SPTOP (sp->ydrag, sp->ywidth), rc.right, sp->ywidth, PATINVERT);
if (sp->dragDone)
sp->ypos = sp->ydrag;
sp->ydrag = -1;
}
if (sp->xdrag >= 0) {
PatBlt (hdc, SPLEFT (sp->xdrag, sp->xwidth), 0, sp->xwidth, rc.bottom, PATINVERT);
if (sp->dragDone)
sp->xpos = sp->xdrag;
sp->xdrag = -1;
}
SelectObject (hdc, hbr);
ReleaseDC (hSplitter, hdc);
if (sp->dragDone) {
int xold = sp->xpos; // Old X-position
int yold = sp->ypos; // Old Y-position
if (sp->xpos <= 0 || sp->xpos >= rc.right)
sp->xpos = -1;
if (sp->ypos <= 0 || sp->ypos >= rc.bottom)
sp->ypos = -1;
sp->dragDone = FALSE;
SpPositionViewWindows (hSplitter);
if ((xold>=0 && sp->xpos<0) || (yold>=0 && sp->ypos<0))
SpNotifyParent (hSplitter, CCSPN_SPLITCHANGED, sp->xpos>=0, sp->ypos>=0);
}
}
return TRUE;
case WM_CREATE:
sp = GlobalAlloc (GPTR, sizeof (*sp));
sp->xpos = sp->xdrag = sp->ypos = sp->ydrag = -1;
sp->xlower = sp->xupper = sp->ylower = sp->yupper = 0;
sp->xwidth = sp->ywidth = CCSP_DEFWIDTH;
SetWindowLong (hSplitter, GWL_SPINFO, (long)sp);
SetWindowLong (hSplitter, GWL_STYLE, GetWindowLong (hSplitter, GWL_STYLE) | WS_CLIPSIBLINGS);
break;
case WM_DESTROY:
GlobalFree (sp);
break;
case WM_LBUTTONDOWN:
dw = GetMessagePos ();
pt.x = GET_X_LPARAM (dw);
pt.y = GET_Y_LPARAM (dw);
ScreenToClient (hSplitter, &pt);
sp->xdrag = CURSORPOS_OK (pt.x, sp->xpos, sp->xwidth) ? pt.x : -1;
sp->ydrag = CURSORPOS_OK (pt.y, sp->ypos, sp->ywidth) ? pt.y : -1;
if (sp->xdrag >=0 || sp->ydrag >= 0) {
GetClientRect (hSplitter, &rc);
hdc = GetDCEx (hSplitter, NULL, DCX_PARENTCLIP);
hbr = SelectObject (hdc, hbrDotty);
if (sp->xdrag >= 0)
PatBlt (hdc, SPLEFT (sp->xdrag, sp->xwidth), 0, sp->xwidth, rc.bottom, PATINVERT);
if (sp->ydrag >= 0)
PatBlt (hdc, 0, SPTOP (sp->ydrag, sp->ywidth), rc.right, sp->ywidth, PATINVERT);
SelectObject (hdc, hbr);
ReleaseDC (hSplitter, hdc);
SetCapture (hSplitter);
}
return TRUE;
case WM_LBUTTONUP:
if (sp->xdrag >= 0 || sp->ydrag >= 0) {
sp->dragDone = TRUE;
ReleaseCapture ();
}
return TRUE;
case WM_MOUSEMOVE:
if (sp->xdrag >= 0 || sp->ydrag >= 0) {
GetClientRect (hSplitter, &rc);
dw = GetMessagePos ();
pt.x = GET_X_LPARAM (dw);
pt.y = GET_Y_LPARAM (dw);
ScreenToClient (hSplitter, &pt);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -