forked from Corran-Raisu/FLCompanion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WndResizer.h
361 lines (293 loc) · 10.2 KB
/
WndResizer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
DISCLAIMER
Auther: Mizan Rahman
Original publication location: http://www.codeproject.com/KB/dialog/WndResizer.aspx
This work is provided under the terms and condition described in The Code Project Open License (CPOL)
(http://www.codeproject.com/info/cpol10.aspx)
This disclaimer should not be removed and should exist in any reproduction of this work.
*/
#pragma once
#include "uxtheme.h"
#define ANCHOR_LEFT 1
#define ANCHOR_TOP 2
#define ANCHOR_RIGHT 4
#define ANCHOR_BOTTOM 8
#define ANCHOR_HORIZONTALLY_CENTERED 16
#define ANCHOR_VERTICALLY_CENTERED 32
#define ANCHOR_PRIORITY_RIGHT 64 // by defualt, left has higher priority
#define ANCHOR_PRIORITY_BOTTOM 128 // by defualt, top has higher priority
#define ANCHOR_VERTICALLY (ANCHOR_TOP | ANCHOR_BOTTOM)
#define ANCHOR_HORIZONTALLY (ANCHOR_LEFT | ANCHOR_RIGHT)
#define ANCHOR_ALL (ANCHOR_VERTICALLY | ANCHOR_HORIZONTALLY)
#define DOCK_NONE 0
#define DOCK_LEFT 1
#define DOCK_TOP 2
#define DOCK_RIGHT 3
#define DOCK_BOTTOM 4
#define DOCK_FILL 5
class CWndResizer
{
public:
CWndResizer(void);
~CWndResizer(void);
private:
class CPanel;
typedef CList<CPanel *, CPanel *> CPanelList;
typedef enum tagSplitterOrientation
{
// a horizontal splitter container panel
SPLIT_CONTAINER_H = 1,
// a vertical splitter contianer panel
SPLIT_CONTAINER_V = 2,
} SplitterOrientation;
typedef enum tagFlowDirection
{
// left to right flow direction
LEFT_TO_RIGHT = 3,
// top to bottom flow direction
TOP_TO_BOTTOM = 4,
} FlowDirection;
class CPanel : public CRect
{
public:
CPanel();
CPanel(const CRect * prc);
virtual ~CPanel();
UINT Anchor;
UINT Dock;
CString Name;
CPanel * Parent;
CPanelList Children;
int LeftOffset;
int TopOffset;
int RightOffset;
int BottomOffset;
CSize MinSize;
CSize MaxSize;
virtual void OnResized();
virtual BOOL AddChild(CPanel * prc);
virtual BOOL RemoveChild(CPanel * prc);
virtual BOOL SetAnchor(UINT anchor);
virtual BOOL SetMinSize(CSize & size);
virtual BOOL SetMaxSize(CSize & size);
virtual CString ToString();
virtual CString GetTypeName();
virtual CWnd * GetHookedWnd();
private:
void Init();
};
class CRootPanel : public CPanel
{
public:
CRootPanel();
~CRootPanel();
virtual CWnd * GetHookedWnd();
CWnd * m_pHookWnd;
virtual CString GetTypeName();
};
class CUIPanel : public CPanel
{
public:
CUIPanel(const CRect * prc, UINT uID);
~CUIPanel();
UINT m_uID; // could be a resource ID or a HWND
BOOL m_bOle; // TRUE= m_uID is an ID of an ActiveX or OLE control, FALSE=regular windows control
virtual CString GetTypeName();
};
class CVisualPanel : public CPanel
{
public:
CVisualPanel();
CVisualPanel(const CRect * prc);
~CVisualPanel();
virtual void Draw(CDC * pDC);
BOOL m_bVisible;
virtual CString GetTypeName();
virtual void OnResized();
private:
CRect m_rcPrev;
};
class CGripperPanel : public CVisualPanel
{
public:
CGripperPanel();
CGripperPanel(const CRect * prc);
~CGripperPanel();
virtual void Draw(CDC * pDC);
virtual CString GetTypeName();
private:
HTHEME m_hTheme;
int m_iPartId;
int m_iStateId;
CString m_sClassName;
};
class CSplitterGripperPanel : public CVisualPanel
{
public:
CSplitterGripperPanel(CWndResizer::SplitterOrientation type);
~CSplitterGripperPanel();
virtual void Draw(CDC * pDC);
virtual CString GetTypeName();
private:
CWndResizer::SplitterOrientation m_OrienType;
};
class CSplitPanel : public CPanel
{
public:
CSplitPanel(CPanel * pPanel);
~CSplitPanel();
virtual BOOL SetAnchor(UINT anchor);
virtual BOOL AddChild(CPanel * prc);
virtual BOOL RemoveChild(CPanel * prc);
virtual CString GetTypeName();
private:
CPanel * m_pOriginalPanel;
};
class CSpitterPanel : public CPanel
{
public:
CSpitterPanel(CWndResizer::SplitterOrientation type);
CSpitterPanel(const CRect * prc, CWndResizer::SplitterOrientation type);
~CSpitterPanel();
virtual CString GetTypeName();
CSplitterGripperPanel * m_pGrippePanel;
private:
CWndResizer::SplitterOrientation m_OrienType;
};
class CSplitContainer : public CPanel
{
public:
CSplitContainer(CSplitPanel * pPanelA, CSplitPanel * pPanelB, CWndResizer::SplitterOrientation type);
~CSplitContainer();
virtual void OnResized();
virtual BOOL AddChild(CPanel * prc);
virtual BOOL RemoveChild(CPanel * prc);
virtual CString GetTypeName();
void SetSplitterPosition(int leftOfSpliter /* or topOfSpliter if vertical */);
int GetSplitterPosition();
void SetFixedPanel(short nFixedPanel /* 1=left or top; 2=right or bototm; other=no fixed panel */);
short GetFixedPanel();
void SetIsSplitterFixed(BOOL bFixed);
BOOL GetIsSplitterFixed();
void SetShowSplitterGrip(BOOL bShow);
BOOL GetShowSplitterGrip();
static CWndResizer::CSplitContainer * Create(CPanel * pPanelA, CPanel * pPanelB);
CWndResizer::SplitterOrientation m_Orientation;
private:
BOOL m_IsSplitterFixed;
short m_FixedPanel; // 1=left or top panel; 2=right or bottom panel, otherwise no fixed panel
double m_nRatio;
int m_nSplitterSize; // for horizontal, it is the splitter width, otherwise it is the splitter height
void GetSplitArea(CRect * pSplitterPanel);
int GetSplitterSize(CPanel * pLeftPanel, CPanel * pRightPanel);
void UpdateRatio();
CSplitPanel * m_pPanelA;
CSplitPanel * m_pPanelB;
CSpitterPanel * m_pSplitter;
};
class CFlowLayoutPanel : public CPanel
{
public:
CFlowLayoutPanel();
CFlowLayoutPanel(const CRect * prc);
~CFlowLayoutPanel();
virtual void OnResized();
virtual CString GetTypeName();
void SetFlowDirection(CWndResizer::FlowDirection direction);
CWndResizer::FlowDirection GetFlowDirection();
void SetItemSpacingX(int nSpace);
int GetItemSpacingX();
void SetItemSpacingY(int nSpace);
int GetItemSpacingY();
private:
int m_nItemSpacingX;
int m_nItemSpacingY;
CWndResizer::FlowDirection m_nFlowDirection;
};
public:
BOOL SetAnchor(LPCTSTR panelName, UINT anchor);
BOOL SetAnchor(UINT panelID, UINT anchor);
BOOL GetAnchor(LPCTSTR panelName, UINT & anchor);
BOOL GetAnchor(UINT panelID, UINT & anchor);
BOOL GetAutoHandlePaint();
BOOL SetAutoHandlePaint(BOOL bHandle);
BOOL SetDock(LPCTSTR panelName, UINT anchor);
BOOL SetDock(UINT panelID, UINT anchor);
BOOL GetDock(LPCTSTR panelName, UINT & anchor);
BOOL GetDock(UINT panelID, UINT & anchor);
BOOL SetFixedPanel(LPCTSTR splitContainerName, short panel);
BOOL GetFixedPanel(LPCTSTR splitContainerName, short & panel);
BOOL SetIsSplitterFixed(LPCTSTR splitContainerName, BOOL fixed);
BOOL GetIsSplitterFixed(LPCTSTR splitContainerName, BOOL &fixed);
BOOL SetFlowDirection(LPCTSTR flowPanelName, short direction);
BOOL GetFlowDirection(LPCTSTR flowPanelName, short &direction);
BOOL SetFlowItemSpacingX(LPCTSTR flowPanelName, int nSpacing);
BOOL GetFlowItemSpacingX(LPCTSTR flowPanelName, int &nSpacing);
BOOL SetFlowItemSpacingY(LPCTSTR flowPanelName, int nSpacing);
BOOL GetFlowItemSpacingY(LPCTSTR flowPanelName, int &nSpacing);
BOOL Draw(CPaintDC * pDC);
BOOL SetShowSplitterGrip(LPCTSTR splitContainerName, BOOL bShow);
BOOL GetShowSplitterGrip(LPCTSTR splitContainerName, BOOL & bShow);
BOOL SetParent(LPCTSTR panelName, LPCTSTR parentName);
BOOL SetParent(UINT panelID, LPCTSTR parentName);
BOOL SetParent(LPCTSTR panelName, UINT parentID);
BOOL SetParent(UINT panelID, UINT parentID);
BOOL GetParent(LPCTSTR panelName, CString & parentName);
BOOL GetParent(UINT panelID, CString & parentName);
BOOL SetMinimumSize(LPCTSTR panelName, CSize & size);
BOOL SetMinimumSize(UINT panelID, CSize & size);
BOOL GetMinimumSize(LPCTSTR panelName, CSize & size);
BOOL GetMinimumSize(UINT panelID, CSize & size);
BOOL SetMaximumSize(LPCTSTR panelName, CSize & size);
BOOL SetMaximumSize(UINT panelID, CSize & size);
BOOL GetMaximumSize(LPCTSTR panelName, CSize & size);
BOOL GetMaximumSize(UINT panelID, CSize & size);
void SetShowResizeGrip(BOOL show = TRUE);
BOOL GetShowResizeGrip();
BOOL Hook(CWnd * pWnd);
BOOL Hook(CWnd * pWnd, CSize & size);
BOOL Unhook();
BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const CRect * prcPanel);
BOOL CreateFlowLayoutPanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE);
BOOL CreatePanel(LPCTSTR panelName, const CRect * prcPanel);
BOOL CreatePanel(LPCTSTR panelName, const CUIntArray * parrID, BOOL setAsChildren = FALSE);
BOOL CreatePanel(UINT uID);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, LPCTSTR panelNameA, LPCTSTR panelNameB);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, LPCTSTR panelNameA, UINT panelIDB);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, UINT panelIDA, UINT panelIDB);
BOOL CreateSplitContainer(LPCTSTR splitContainerName, UINT panelIDA, LPCTSTR panelNameB);
// useful for persisting UI layout
BOOL SetSplitterPosition(LPCTSTR splitContainerName, UINT position);
BOOL GetSplitterPosition(LPCTSTR splitContainerName, UINT & position);
BOOL InvokeOnResized();
CString GetDebugInfo();
private:
CWnd * m_pHookedWnd;
CRootPanel root;
CPanel * m_pCaptured;
HCURSOR m_hOldCursor;
int m_splitterOffset;
BOOL m_bAutoHandlePaint;
void OnPaint();
void OnSize(UINT nType, int cx, int cy);
void OnSizing(UINT fwSide, LPRECT pRect);
void OnScroll();
void OnDestroy();
void OnLButtonDown(UINT nFlags, CPoint point);
void OnMouseMove(UINT nFlags, CPoint point);
void OnLButtonUp(UINT nFlags, CPoint point);
CWndResizer::CPanel * FindPanelByName(CWndResizer::CPanel * pRoot, LPCTSTR name);
CWndResizer::CPanel * FindSplitterFromPoint(CWndResizer::CPanel * pRoot, CPoint point);
void GetUIPanels(CWndResizer::CPanel * pRoot, CPanelList * pList, BOOL bOle);
void GetVisualPanels(CWndResizer::CPanel * pRoot, CPanelList * pList);
void ResizeUI(CWndResizer::CPanel * pRoot);
CString IdToName(UINT uID);
CWndResizer::CUIPanel * CreateUIPanel(UINT uID);
CWndResizer::CUIPanel * GetUIPanel(UINT uID);
void UpdateSplitterOffset(CPoint ptCurr);
void GetDebugInfo(CPanel * pRoot, CString & info, CString indent);
void GetTrueClientRect(CWnd * pWnd, CRect * prc);
void EnsureRootMinMax();
WNDPROC m_pfnWndProc;
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};