/
DataWinForm.prg
374 lines (328 loc) · 12.7 KB
/
DataWinForm.prg
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
361
362
363
364
365
366
367
368
369
370
371
372
373
374
//
// Copyright (c) XSharp B.V. All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
// DataForm.prg
USING SWF := System.Windows.Forms
USING System.Drawing
USING VOSDK := XSharp.VO.SDK
#pragma warnings (9043, disable) // Controls is ambiguous
#define INSIDEFORMBORDER 5
/*
For MDI Child windows this looks like:
.--------------------------------------------
| Toolbar Area |
.--------------------------------------------
| SurfacePanel | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
|................................. |
|FramePanel |
| |
.--------------------------------------------
| Statusbar Area |
.--------------------------------------------
Subwindows consist of:
.--------------------------------------------
| SurfacePanel | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
|................................. |
|FramePanel |
.--------------------------------------------
When the surface is smaller than the framepanel, then that panel will fill the window
When the srface is bigger than the Framepanel, then that panel will show the scrollbars
When the datawindow is in browse view, then the browser has the size of the frame panel and no
scrollbars are shown on the framepanel
*/
CLASS VODataForm INHERIT VOChildAppForm
#region Fields
PROTECT oSurfacePanel AS VoSurfacePanel // This is the place where the controls are drawn
protect oFramePanel as VoFramePanel // This is a panel on which the Surface sits. When the window is too small this panel will show the scrollbars
PROTECT oToolBar AS VOToolBar
PROTECT oStatusBar AS VOStatusBar
PROTECT oResDlg AS ResourceDialog
PROTECT lInBrowseView AS LOGIC
PROTECT oDataBrowser AS SWF.Control
#endregion
#region Properties
PROPERTY Origin AS VOSDK.Point GET SELF:Location SET SELF:Location := Value
PROPERTY Surface AS VoSurfacePanel GET oSurfacePanel
property Frame as VOFramePanel get oFramePanel
PROPERTY AutoLayout AS LOGIC AUTO GET SET
PROPERTY DataBrowser AS SWF.Control
GET
RETURN oDataBrowser
END GET
SET
IF oDataBrowser != Value
IF oDataBrowser != NULL_OBJECT
oDataBrowser:GotFocus -= OnBrowserGotFocus
oDataBrowser:LostFocus -= OnBrowserLostFocus
ENDIF
oDataBrowser := Value
IF oDataBrowser != NULL_OBJECT
oFramePanel:Controls:Add(oDataBrowser)
oDataBrowser:Visible := FALSE
oDataBrowser:Dock := SWF.DockStyle.Fill
oDataBrowser:BringToFront()
oDataBrowser:GotFocus += OnBrowserGotFocus
oDataBrowser:LostFocus += OnBrowserLostFocus
ENDIF
ENDIF
SELF:AdjustSizes()
END SET
END PROPERTY
PROPERTY DataWindow AS VOSDK.DataWindow GET (DataWindow) Window
PROPERTY StatusBar AS VOStatusBar
GET
RETURN oStatusBar
END GET
SET
oStatusBar := Value
IF oStatusBar != NULL_OBJECT
SELF:Controls:Add((SWF.Control) oStatusBar)
oStatusBar:Dock := SWF.DockStyle.Bottom
oStatusBar:TabIndex := 3
SELF:PerformLayout()
ENDIF
END SET
END PROPERTY
PROPERTY SubForm AS LOGIC AUTO GET SET
PROPERTY ToolBar AS VOToolBar
GET
RETURN oToolBar
END GET
SET
IF Value != NULL_OBJECT
oToolBar := Value
SELF:Controls:Add(oToolBar)
oToolBar:Dock := SWF.DockStyle.Top
oToolBar:TabIndex := 1
SELF:PerformLayout()
SELF:AdjustSizes()
SELF:AdjustFrameSize()
ENDIF
END SET
END PROPERTY
#endregion
#region Winforms event handlers
PRIVATE METHOD OnBrowserGotFocus(sender AS OBJECT, e AS EventArgs) AS VOID
IF SELF:SubForm .AND. SELF:Window != NULL_OBJECT
SELF:Window:Activate(Event{})
ENDIF
PRIVATE METHOD OnBrowserLostFocus(sender AS OBJECT, e AS EventArgs) AS VOID
IF SELF:SubForm .AND. SELF:Window != NULL_OBJECT
SELF:Window:Deactivate(Event{})
ENDIF
#endregion
CONSTRUCTOR(oWindow AS Window, oOwner AS SWF.Form, oRes AS ResourceDialog)
SUPER(oWindow, oOwner)
SELF:oResDlg := oRes
SELF:Text := "DataWinForm"
// Form owns the frame
oFramePanel := GuiFactory.Instance:CreateFramePanel(SELF, oWindow)
SELF:Controls:Add((SWF.Control) oFramePanel)
// Frame owns the surface
oSurfacePanel := GuiFactory.Instance:CreateSurfacePanel(oWindow)
oFramePanel:Controls:Add(oSurfacePanel)
IF oRes != NULL_OBJECT
oSurfacePanel:Size := oRes:Size
oSurfacePanel:MinimumSize := oRes:Size
ELSE
oSurfacePanel:Size := SELF:ClientRectangle:Size
ENDIF
oFramePanel:Size := oSurfacePanel:Size
SELF:AdjustFrameSize()
#region Winforms Method overrides
OVERRIDE PROTECT METHOD OnShown(e AS EventArgs) AS VOID STRICT
FOREACH oC AS SWF.Control IN SELF:Surface:Controls
IF oC IS VOButton VAR oVOB
IF oVOB:DefaultButton
SELF:AcceptButton := (SWF.IButtonControl) oVOB
ENDIF
ENDIF
NEXT
SUPER:OnShown(e)
SELF:SelectFirstControl()
PROTECTED METHOD SelectFirstControl() AS SWF.Control STRICT
VAR oFirst := SELF:GetFirstEditableControl()
IF oFirst != NULL_OBJECT
oFirst:Select()
ENDIF
RETURN oFirst
OVERRIDE PROTECT METHOD OnSizeChanged(e AS EventArgs ) AS VOID
SUPER:OnSizeChanged(e)
IF SELF:Visible
SELF:AdjustSizes()
ENDIF
RETURN
#endregion
#region Other methods to preproduce the VO DataWIndow behavior
METHOD AdjustSizes() AS VOID STRICT
LOCAL oSize AS Size
// This is called when resizing and/or when toolbar or statusbar is shown
// it recalculates the size of the framepanel
// DebOut(__FUNCTION__)
SELF:SuspendLayout()
IF ! SELF:SubForm
oSize := SELF:ClientRectangle:Size
IF oToolBar != NULL_OBJECT
oSize:Height -= oToolBar:Height
SELF:oFramePanel:Location := System.Drawing.Point{0,oToolBar:Height}
ELSE
SELF:oFramePanel:Location := System.Drawing.Point{0,0}
ENDIF
IF oStatusBar != NULL_OBJECT //.and. oStatusBar:Visible
oSize:Height -= oStatusBar:Height
ENDIF
IF oFramePanel:Size:Width != oSize:Width .OR. oFramePanel:Size:Height != oSize:Height
oFramePanel:Size := oSize
ENDIF
ENDIF
IF lInBrowseView
oDataBrowser:Dock := SWF.DockStyle.Fill
oFramePanel:AutoScroll := FALSE
ELSE
oFramePanel:AutoScroll := TRUE
ENDIF
SELF:ResumeLayout()
RETURN
METHOD AdjustFrameSize() AS VOID STRICT
// Adjust outer window so it fits just around the surface
LOCAL oOuterSize AS Size
LOCAL oInnerSize AS Size
LOCAL nBordX, nBordY AS LONG
LOCAL oLoc AS System.Drawing.Point
SELF:SuspendLayout()
//DebOut(__FUNCTION__)
IF SELF:SubForm
NOP
ELSE
oLoc := SELF:Location
oOuterSize := SELF:Size
oInnerSize := SELF:ClientRectangle:Size
nBordX := oOuterSize:Width - oInnerSize:Width
nBordY := oOuterSize:Height - oInnerSize:Height
// Calculate wanted outer size based on Surface Size
//oSurfacePanel:MinimumSize := System.Drawing.Size.Empty
oSurfacePanel:AutoSizeMode := SWF.AutoSizeMode.GrowAndShrink
oSurfacePanel:PerformLayout()
oInnerSize := oSurfacePanel:Size
SELF:oFramePanel:Size := oInnerSize
oOuterSize:Width := oInnerSize:Width + nBordX + INSIDEFORMBORDER
oOuterSize:Height := oInnerSize:Height + nBordY + INSIDEFORMBORDER
IF oToolBar != NULL_OBJECT //.and. oToolBar:Visible
oOuterSize:Height += oToolBar:Height
ENDIF
IF oStatusBar != NULL_OBJECT //.and. oStatusBar:Visible
oOuterSize:Height += oStatusBar:Height
ENDIF
SELF:Size := oOuterSize
SELF:Location := oLoc
ENDIF
SELF:ResumeLayout()
RETURN
METHOD ChangeFormSize(oDim AS Size) AS VOID
//DebOut(__FUNCTION__)
SELF:Size := oDim
RETURN
METHOD CreateSubForm(nResourceID AS LONG, oResDlg AS ResourceDialog) AS LOGIC
LOCAL oItem AS ResourceDialogItem
SELF:SubForm := TRUE
oItem := oResDlg:GetDlgItem(nResourceID)
IF oItem != NULL_OBJECT
SELF:oFramePanel:Location := oItem:Origin
SELF:oFramePanel:Size := oItem:Size
SELF:oFramePanel:DefinedSize := oItem:Size
SELF:oFramePanel:Visible := TRUE
SELF:oFramePanel:AutoScroll := FALSE
SELF:oFramePanel:IsSubForm := TRUE
IF oItem:TabIndex > 0
SELF:oFramePanel:TabIndex := oItem:TabIndex
ENDIF
ENDIF
RETURN TRUE
METHOD ResetMinSize() AS VOID
RETURN
METHOD HideSubForm () AS VOID STRICT
SELF:Frame:Visible := FALSE
RETURN
METHOD ShowSubForm () AS VOID STRICT
SELF:oFramePanel:Visible := TRUE
IF SELF:lInBrowseView
SELF:oDataBrowser:Visible := TRUE
SELF:oDataBrowser:Dock := SWF.DockStyle.Fill
SELF:oFramePanel:Size := SELF:oFramePanel:DefinedSize
ELSE
SELF:oSurfacePanel:Visible := TRUE
ENDIF
SELF:Frame:Prepare()
RETURN
METHOD SetFocusToForm ( ) AS VOID STRICT
IF SELF:lInBrowseView
oDataBrowser:Focus()
ELSEIF (oSurfacePanel != NULL_OBJECT)
oSurfacePanel:Focus()
ENDIF
RETURN
METHOD ViewAs(lBrowse AS LOGIC) AS VOID
oFramePanel:SuspendLayout()
IF lBrowse
IF (oDataBrowser== NULL_OBJECT)
RETURN
ENDIF
oSurfacePanel:Visible := FALSE
IF oFramePanel:Controls:Contains(oSurfacePanel)
oFramePanel:Controls:Remove(oSurfacePanel)
ENDIF
oFramePanel:Controls:Add(oDataBrowser)
oFramePanel:AutoScroll := FALSE
oDataBrowser:Visible := TRUE
oDataBrowser:Dock := SWF.DockStyle.Fill
oDataBrowser:Focus()
ELSE
// Show the dialog and hide the GBRowse
IF (oDataBrowser != NULL_OBJECT)
oDataBrowser:Visible := FALSE
IF oFramePanel:Controls:Contains(oDataBrowser)
oFramePanel:Controls:Remove(oDataBrowser)
ENDIF
ENDIF
oFramePanel:Controls:Add(oSurfacePanel)
oFramePanel:AutoScroll := TRUE
oSurfacePanel:Visible := TRUE
ENDIF
oFramePanel:Prepare()
oFramePanel:ResumeLayout(TRUE)
SELF:lInBrowseView := lBrowse
SELF:AdjustSizes()
RETURN
PUBLIC METHOD SuspendRedraw AS VOID
//DebOut(__FUNCTION__)
IF SELF:lInBrowseView
GuiWin32.SendMessage(SELF:Frame:Handle, WM_SETREDRAW, 0, 0)
ELSE
GuiWin32.SendMessage(SELF:Surface:Handle, WM_SETREDRAW, 0, 0)
ENDIF
PUBLIC METHOD ResumeRedraw AS VOID
//DebOut(__FUNCTION__)
IF SELF:lInBrowseView
GuiWin32.SendMessage(SELF:Frame:Handle, WM_SETREDRAW, 1, 0)
ELSE
GuiWin32.SendMessage(SELF:Surface:Handle, WM_SETREDRAW, 1, 0)
ENDIF
SELF:Refresh()
#endregion
END CLASS