📄 dockmgr.c
字号:
/*
Copyright 2001-2003 Free Software Foundation, Inc.
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
**********************************************************************
DOCKMGR.C is the main code involved in dealing with dockable windows.
The windows get registered with this routine, and various messages
are sent to this to help it manage and relocate the dockable windows.
It also handles undocking and linking toolbars to parent MDI windows
when undocked.
**********************************************************************
*/
#include <windows.h>
#include <commctrl.h>
#include <Stdio.h>
#include "header.h"
#include "winconst.h"
#define FRAMEWIDTH 8
#define GRIPWIDTH 15
#define MIN_WIDTH 30
#define DEFAULT_WIDTH 200
#define DEFAULT_HEIGHT 160
#define TITLE_ALIAS 25
#define MIN_SIZE (21)
extern HWND hwndSourceTab;
static CCW_params **cache;
static CCD_params **docks;
static int max, currentWindows;
static HWND hwndFrame, hwndClient;
static RECT moverect;
static POINT movept;
static int curstype;
static int moving = 0;
static int sizing = 0;
static RECT lastbound;
static int drawnbound;
static int suggestedDock, lastSuggestedDock;
static int frameCount, frameMax;
static int blankCount, blankMax;
static int gripCount, gripMax;
static int containerCount, containerMax;
static CFW_params *frames[30];
static CCW_params *blanks[30], *grips[30], *containers[30];
static HWND sbwnd;
static int sbheight;
static int rundown;
static HBITMAP hFocusBitmap;
int dock(CCW_params *p, RECT *r);
CCD_params *FindParams(CCW_params *p, int *index);
void CalculateMoveableDocks(CCW_params *p, RECT *r, POINT *pt);
void DoDocks(CCW_params *p);
void CalculateLayout(int index, int recalhidden);
void CalculateSizebarBounds(CFW_params *p, RECT *dest);
void Resize(CFW_params *p, RECT *new);
void PutWindow(HWND hwnd, RECT *r);
void CalculateHidden(CCD_params *d, int index, int state);
void InsertVertFrame(int index, int left, RECT *fullframe);
void InsertHorizFrame(int index, int top, int fullframe);
CCD_params *FindParams(CCW_params *p, int *index)
{
int i;
for (i = 0; i < currentWindows; i++)
if (cache[i] == p)
{
if (index)
*index = i;
return docks[i];
}
return NULL;
}
//-------------------------------------------------------------------------
void DrawBoundingRect(RECT *r1)
{
static int drawn;
static HDC hdcMem, dc;
static HBITMAP bm;
HBRUSH brush, oldbrush;
RECT r3 = *r1, r2;
int i;
if (!drawn)
{
dc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
hdcMem = CreateCompatibleDC(dc);
bm = CreateCompatibleBitmap(dc, r1->right - r1->left, r1->bottom - r1
->top);
SelectObject(hdcMem, bm);
BitBlt(hdcMem, 0, 0, r1->right - r1->left, r1->bottom - r1->top, dc, r1
->left, r1->top, SRCCOPY);
brush = CreatePatternBrush(hFocusBitmap);
oldbrush = SelectObject(dc, brush);
for (i = 0; i < 4; i++)
{
FrameRect(dc, &r3, brush);
r3.left++;
r3.right--;
r3.top++;
r3.bottom--;
}
SelectObject(dc, oldbrush);
DeleteObject(brush);
}
else
{
BitBlt(dc, r1->left, r1->top, r1->right - r1->left, r1->bottom - r1
->top, hdcMem, 0, 0, SRCCOPY);
DeleteDC(hdcMem);
DeleteDC(dc);
DeleteObject(bm);
}
drawn = !drawn;
#ifdef XXXXX
for (i = 0; i < 4; i++)
{
DrawFocusRect(dc, &r3);
r3.left++;
r3.right--;
r3.top++;
r3.bottom--;
}
#endif
lastbound = *r1;
drawnbound = TRUE;
}
//-------------------------------------------------------------------------
void GetRelativeRect(HWND parent, HWND self, RECT *r)
{
POINT pt;
GetWindowRect(self, r);
pt.x = r->left;
pt.y = r->top;
ScreenToClient(parent, &pt);
r->bottom = r->bottom - r->top + pt.y;
r->right = r->right - r->left + pt.x;
r->left = pt.x;
r->top = pt.y;
}
//-------------------------------------------------------------------------
void GetFrameWindowRect(RECT *r)
{
GetWindowRect(hwndFrame, r);
r->top += GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYMENU) +
GetSystemMetrics(SM_CYFRAME);
r->bottom -= GetSystemMetrics(SM_CYFRAME);
r->left += GetSystemMetrics(SM_CXFRAME);
r->right -= GetSystemMetrics(SM_CXFRAME);
r->bottom -= sbheight;
}
//-------------------------------------------------------------------------
void AllocContainer(CCW_params *p, RECT *r, int reshow)
{
SendMessage(p->self, LCF_SETVERTICAL, 0, 0);
if (containerCount >= containerMax)
CreateContainerWindow(hwndClient, r);
containers[containerCount]->parent = p->parent;
containers[containerCount]->u.gp.child = p->self;
if (p->type != LSTOOLBAR)
{
// relies on the next higher window being the top...
containers[containerCount]->u.gp.directchild = p->parent;
SendMessage(p->self, LCF_CONTAINER, 0, 1);
SetParent(p->parent, containers[containerCount]->self);
MoveWindow(containers[containerCount]->self, r->left, r->top, r->right
- r->left + 2 * GetSystemMetrics(SM_CXFRAME), r->bottom - r->top +
GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME), 1);
ShowWindow(p->parent, SW_SHOW);
}
else
{
containers[containerCount]->u.gp.directchild = p->self;
SetParent(p->self, containers[containerCount]->self);
MoveWindow(containers[containerCount]->self, r->left, r->top, p
->u.tb.hsize.cx + 2 * GetSystemMetrics(SM_CXFRAME), p
->u.tb.hsize.cy + GetSystemMetrics(SM_CYCAPTION), 1);
}
p->parent = containers[containerCount]->self;
// parent is the frame here, not the real parent
SendMessage(containers[containerCount]->self, WM_SETTEXT, 0, (LPARAM)p
->title);
if (reshow)
ShowWindow(containers[containerCount]->self, SW_SHOW);
containerCount++;
}
//-------------------------------------------------------------------------
void FreeContainer(CCW_params *ps)
{
int i;
CCW_params *p = (CCW_params*)GetWindowLong(ps->parent, 0);
if (!p || p->type != LSTBCONT)
return ;
ShowWindow(ps->parent, SW_HIDE);
ps->parent = p->parent;
// TBCONT parent field was munged to hold original parent
if (ps->type != LSTOOLBAR)
{
SendMessage(ps->self, LCF_CONTAINER, 0, 0);
}
for (i = 0; i < containerMax; i++)
if (p == containers[i])
break;
memcpy(containers + i, containers + i + 1, (containerMax - i - 1) *sizeof
(CCW_params*));
containers[containerMax - 1] = p;
containerCount--;
}
//-------------------------------------------------------------------------
void AllocGrip(CCW_params *p, RECT *r, int vertical, int reshow)
{
if (p->type != LSTOOLBAR)
return ;
SendMessage(p->self, LCF_SETVERTICAL, GRIPWIDTH, vertical);
if (gripCount >= gripMax)
CreateGripWindow(hwndClient, r, vertical);
SendMessage(grips[gripCount]->self, LCF_SETVERTICAL, 0, vertical);
grips[gripCount]->u.gp.child = p->self;
SetParent(p->self, grips[gripCount]->self);
p->parent = grips[gripCount]->self;
if (vertical)
MoveWindow(grips[gripCount]->self, r->left, r->top, p->u.tb.vsize.cx, p
->u.tb.vsize.cy + GRIPWIDTH, 1);
else
MoveWindow(grips[gripCount]->self, r->left, r->top, p->u.tb.hsize.cx +
GRIPWIDTH, p->u.tb.hsize.cy, 1);
if (reshow)
ShowWindow(grips[gripCount]->self, SW_SHOW);
gripCount++;
}
//-------------------------------------------------------------------------
void FreeGrip(CCW_params *ps)
{
int i;
CCW_params *p;
if (ps->type != LSTOOLBAR)
return ;
p = (CCW_params*)GetWindowLong(ps->parent, 0);
ShowWindow(ps->parent, SW_HIDE);
for (i = 0; i < gripMax; i++)
if (p == grips[i])
break;
memcpy(grips + i, grips + i + 1, (gripMax - i - 1) *sizeof(CCW_params*));
grips[gripMax - 1] = p;
gripCount--;
}
//-------------------------------------------------------------------------
void AllocBlank(RECT *r, CCD_params *d, int vertical)
{
if (blankCount >= blankMax)
CreateBlankWindow(hwndFrame, r);
blanks[blankCount]->u.bw.position = *r;
blanks[blankCount]->u.bw.representative_dock = d;
MoveWindow(blanks[blankCount++]->self, r->left, r->top, r->right - r->left,
r->bottom - r->top, 1);
}
//-------------------------------------------------------------------------
void dmgrAddStatusBar(HWND sb)
{
RECT r;
sbwnd = sb;
GetWindowRect(sb, &r);
sbheight = r.bottom - r.top;
}
//-------------------------------------------------------------------------
void GetClientWindowRect(RECT *r)
{
GetWindowRect(hwndClient, r);
r->top -= SendMessage(hwndSourceTab, WM_GETHEIGHT, 0, 0);
}
//-------------------------------------------------------------------------
void dmgrInit(HINSTANCE hInstance, HWND frame, HWND client, int count)
{
hFocusBitmap = LoadBitmap(hInstance, "ID_BRFOCUS");
hwndFrame = frame;
hwndClient = client;
cache = malloc(count *sizeof(CCW_params*));
if (cache)
{
docks = malloc(count *sizeof(CCD_params*));
if (!docks)
{
free(cache);
cache = 0;
}
}
if (cache)
max = count;
}
//-------------------------------------------------------------------------
void dmgrAddClient(CCW_params *p)
{
RECT r;
if (currentWindows < max)
{
int style = GetWindowLong(p->parent, GWL_STYLE);
CCD_params *s = calloc(sizeof(CCD_params), 1);
if (!s)
return ;
s->hidden = !(style &WS_VISIBLE);
cache[currentWindows] = p;
docks[currentWindows++] = s;
GetWindowRect(p->parent, &s->position);
s->lastposition = s->position;
s->lastposition.right -= s->lastposition.left;
s->lastposition.bottom -= s->lastposition.top;
s->lastposition.left = s->lastposition.top = 0;
s->oldsize = s->lastposition;
if (p->type == LSTOOLBAR)
{
memset(&r, 0, sizeof(r));
AllocContainer(p, &r, FALSE);
ShowWindow(p->parent, SW_HIDE);
}
}
}
//-------------------------------------------------------------------------
int dmgrRemoveClient(CCW_params *p)
{
int i;
CCD_params *d;
for (i = 0; i < currentWindows; i++)
{
GetWindowRect(cache[i]->parent, &docks[i]->position);
}
d = FindParams(p, &i);
if (d)
{
free(d);
memmove(&docks[i], &docks[i + 1], sizeof(CCD_params*) * currentWindows
- i - 1);
memmove(&cache[i], &cache[i + 1], sizeof(CCW_params*) * currentWindows
- i - 1);
currentWindows--;
CalculateLayout( - 1, 0);
}
}
//-------------------------------------------------------------------------
void dmgrAddFrame(CFW_params *p)
{
frames[frameMax++] = p;
}
//-------------------------------------------------------------------------
void dmgrAddBlank(CCW_params *p)
{
blanks[blankMax++] = p;
}
//-------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -