source: trunk/mainwin.cpp@ 2

Last change on this file since 2 was 2, checked in by Gregg Young, 7 years ago

Gotcha 1.78 source from Hobbes

  • Property svn:eol-style set to native
File size: 17.6 KB
RevLine 
[2]1/***
2 This file belongs to the Gotcha! distribution.
3 Copyright (C) 1998-2002 Thorsten Thielen <thth@c2226.de>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ***/
19
20// ** CreateMainWindow **************************************************** /*fold00*/
21
22HWND CreateMainWindow (VOID)
23{
24 hwndFrame = WinLoadDlg (HWND_DESKTOP, NULLHANDLE, NULL, GETMODULE,
25 ID_DLG_MAIN, NULL);
26 OldFrameWP = WinSubclassWindow (hwndFrame, FrameProcedure);
27
28 // attach the icon
29 if (HPOINTER hicon = WinLoadPointer (HWND_DESKTOP, GETMODULE, 1))
30 WinSendMsg (hwndFrame, WM_SETICON, MPFROMLONG (hicon), NULL);
31
32 // attach the accelerator table
33 if (HACCEL haccel = WinLoadAccelTable (hab, GETMODULE, 1))
34 WinSetAccelTable (hab, haccel, hwndFrame);
35
36 // add extensions to system menu
37 static MENUITEM MenuAbout = { MIT_END, MIS_TEXT, 0, WID_PB_ABOUT, 0, 0 };
38 static MENUITEM MenuSettings = { MIT_END, MIS_TEXT, 0, WID_PB_SETTINGS, 0, 0 };
39 static MENUITEM MenuGeneralHelp = { MIT_END, MIS_TEXT, 0, HM_GENERAL_HELP, 0, 0 };
40 static MENUITEM MenuSeparator = { MIT_END, MIS_SEPARATOR, 0, 0, 0, 0 };
41
42 AddSysMenuItem (hwndFrame, &MenuSeparator, NULL);
43 AddSysMenuItem (hwndFrame, &MenuSettings, RSTR(IDS_SETTINGS));
44 AddSysMenuItem (hwndFrame, &MenuGeneralHelp, RSTR(IDS_GENERALHELP));
45 AddSysMenuItem (hwndFrame, &MenuAbout, RSTR(IDS_PRODUCTINFORMATION));
46
47 HWND hwnd = WinWindowFromID (hwndFrame, FID_CLIENT);
48
49 // select the radio button
50 switch (pset->QuerySaveStyle ())
51 {
52 case SAVESTYLE_CLIPBOARD:
53 WinSendDlgItemMsg (hwnd, WID_RB_CLIPBOARD, BM_CLICK,
54 MPFROMSHORT (TRUE), 0); break;
55 default:
56 WinSendDlgItemMsg (hwnd, WID_RB_FILE, BM_CLICK,
57 MPFROMSHORT (TRUE), 0); break;
58 }
59 AdjustSaveTypeButtons (BOOL (pset->QueryFileSaveStyle ()==FSS_FORCEFILE));
60
61 if (pset->SerialCapture ())
62 WinEnableWindow (WinWindowFromID (hwnd, WID_CB_DELAYEDCAPTURE), FALSE);
63
64 // adjust the other buttons
65 WinSendDlgItemMsg (hwnd, WID_CB_HIDEWINDOW, BM_SETCHECK,
66 MPFROMLONG (pset->HideWindow ()), MPFROMLONG (0));
67 WinSendDlgItemMsg (hwnd, WID_CB_DELAYEDCAPTURE, BM_SETCHECK,
68 MPFROMLONG (pset->DelayedCapture ()), MPFROMLONG (0));
69 return hwndFrame;
70}
71
72// ** Drag **************************************************************** /*fold00*/
73
74VOID Drag (HWND hwnd)
75{
76 // determine the new window position
77 TRACKINFO trackinfo ;
78 memset (&trackinfo, 0, sizeof (trackinfo));
79
80 trackinfo.cxBorder = 1;
81 trackinfo.cyBorder = 1;
82 trackinfo.cxGrid = 1;
83 trackinfo.cyGrid = 1;
84 trackinfo.cxKeyboard = 8;
85 trackinfo.cyKeyboard = 8;
86
87 SWP swp;
88 WinQueryWindowPos (hwnd, &swp);
89 trackinfo.rclTrack.xLeft = swp.x;
90 trackinfo.rclTrack.xRight = swp.x + swp.cx;
91 trackinfo.rclTrack.yBottom = swp.y;
92 trackinfo.rclTrack.yTop = swp.y + swp.cy;
93
94 WinQueryWindowPos (HWND_DESKTOP, &swp);
95 trackinfo.rclBoundary.xLeft = swp.x;
96 trackinfo.rclBoundary.xRight = swp.x + swp.cx;
97 trackinfo.rclBoundary.yBottom = swp.y;
98 trackinfo.rclBoundary.yTop = swp.y + swp.cy;
99
100 trackinfo.ptlMinTrackSize.x = 0;
101 trackinfo.ptlMinTrackSize.y = 0;
102 trackinfo.ptlMaxTrackSize.x = swp.cx;
103 trackinfo.ptlMaxTrackSize.y = swp.cy;
104
105 trackinfo.fs = TF_MOVE | TF_STANDARD | TF_ALLINBOUNDARY;
106
107 if (WinTrackRect (HWND_DESKTOP, 0, &trackinfo))
108 WinSetWindowPos (hwnd, 0, trackinfo.rclTrack.xLeft,
109 trackinfo.rclTrack.yBottom, 0, 0, SWP_MOVE);
110}
111
112// ** FrameProcedure ****************************************************** /*fold00*/
113
114MRESULT EXPENTRY FrameProcedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
115{
116 // ATTENTION: used by both main & snapshot window!
117
118 switch (msg)
119 {
120 case WM_QUERYTRACKINFO:
121 {
122 OldFrameWP (hwnd, msg, mp1, mp2);
123 PTRACKINFO pti = PTRACKINFO (mp2);
124 pti->ptlMinTrackSize.x = pti->ptlMinTrackSize.y = 16;
125 }
126 return MRESULT (TRUE);
127
128 case WM_WINDOWPOSCHANGED:
129 if ((PSWP (mp1)->fl & SWP_HIDE))
130 WinPostMsg (WinWindowFromID (hwnd, FID_CLIENT),
131 UM_WINDOWHIDDEN, 0,0);
132 break;
133 }
134
135 return OldFrameWP (hwnd, msg, mp1, mp2);
136}
137
138// ** WindowProcedure ***************************************************** /*FOLD00*/
139
140MRESULT EXPENTRY WindowProcedure (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
141{
142 static BOOL fInterior = FALSE;
143 static USHORT usState = STATE_IDLE, usCap;
144 static ULONG ulTimer, ulCountdown;
145 static HWND hwndCap, hwndParent;
146 static RECTL rcl;
147
148#ifdef _DOLOGDEBUG_
149 LogDebug( "MainWin:WindowProcedure:Message 0x%04x", msg );
150#endif
151
152 switch (msg)
153 {
154 case WM_CREATE:
155 {
156#ifdef _DOLOGDEBUG_
157 LogDebug( "MainWin:WindowProcedure: WM_CREATE" );
158#endif
159 USHORT usResID = WinQueryWindowUShort (hwnd, QWS_ID);
160
161 // attach the icon
162 if (HPOINTER hicon = WinLoadPointer (HWND_DESKTOP, GETMODULE, usResID))
163 WinSendMsg (hwnd, WM_SETICON, MPFROMLONG (hicon), MPVOID);
164
165 RECTL rcl;
166 WinQueryWindowRect (hwndFrame, &rcl);
167 WinCalcFrameRect (hwndFrame, &rcl, TRUE);
168 WinSetWindowPos (WinWindowFromID (hwndFrame, FID_CLIENT), HWND_TOP,
169 rcl.xLeft, rcl.yBottom, rcl.xRight - rcl.xLeft,
170 rcl.yTop - rcl.yBottom,
171 SWP_SHOW | SWP_MOVE | SWP_SIZE | SWP_ZORDER);
172 }
173 break;
174
175 case WM_QUIT:
176#ifdef _DOLOGDEBUG_
177 LogDebug( "MainWin:WindowProcedure: WM_QUIT" );
178#endif
179 case WM_SAVEAPPLICATION:
180#ifdef _DOLOGDEBUG_
181 LogDebug( "MainWin:WindowProcedure: WM_SAVEAPPLICATION" );
182#endif
183 case WM_CLOSE:
184#ifdef _DOLOGDEBUG_
185 LogDebug( "MainWin:WindowProcedure: WM_CLOSE" );
186#endif
187 WinSendMsg (hwnd, UM_ADJUSTSETTINGS, 0,0);
188 break;
189
190 case UM_ADJUSTSETTINGS:
191 {
192#ifdef _DOLOGDEBUG_
193 LogDebug( "MainWin:WindowProcedure: UM_ADJUSTSETTINGS" );
194#endif
195 if (WinSendMsg (WinWindowFromID (hwnd, WID_RB_CLIPBOARD),
196 BM_QUERYCHECK, 0,0))
197 pset->SetSaveStyle (SAVESTYLE_CLIPBOARD);
198 else
199 pset->SetSaveStyle (SAVESTYLE_FILE);
200
201 BOOL f = FALSE;
202 f = BOOL (WinSendDlgItemMsg (hwnd, WID_CB_HIDEWINDOW,
203 BM_QUERYCHECK, 0, 0));
204 pset->HideWindow (f);
205
206 f = BOOL (WinSendDlgItemMsg (hwnd, WID_CB_DELAYEDCAPTURE,
207 BM_QUERYCHECK, 0, 0));
208 pset->DelayedCapture (f);
209 }
210 return MRESULT (FALSE);
211
212 case WM_MOUSEMOVE:
213 // we don't want the mouse pointer to be reset so capture this msg
214 return MRESULT (FALSE);
215
216 case WM_PAINT:
217 {
218 HPS hps;
219 RECTL rcl;
220 COLOR color = SYSCLR_DIALOGBACKGROUND;
221
222 HWND hwnd2 = WinWindowFromID (hwnd, WID_RB_CLIPBOARD);
223 WinQueryPresParam (hwnd2, PP_BACKGROUNDCOLOR, 0, NULL,
224 sizeof (color), &color, 0L);
225
226 hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
227 WinQueryWindowRect (hwnd, &rcl);
228 WinFillRect (hps, &rcl, color);
229 WinEndPaint (hps);
230 }
231 break;
232
233 case WM_COMMAND:
234#ifdef _DOLOGDEBUG_
235 LogDebug( "MainWin:WindowProcedure: WM_COMMAND" );
236#endif
237 if (usState != STATE_IDLE)
238 {
239 // this means ESC was pressed
240 if (SHORT1FROMMP (mp1) == DID_CANCEL)
241 WinSendMsg (hwnd, UM_ABORT, 0,0);
242 return MRESULT (FALSE);
243 }
244 else
245 // FIXME pretty yukki to do it this way I guess ...
246 WinSendMsg (hwnd, UM_ADJUSTSETTINGS, 0,0);
247
248 switch (SHORT1FROMMP (mp1))
249 {
250 case WID_RB_CLIPBOARD:
251 WinSendDlgItemMsg (hwnd, WID_RB_CLIPBOARD, BM_CLICK,
252 MPFROMSHORT (TRUE), PVOID (0));
253 break;
254 case WID_RB_FILE:
255 WinSendDlgItemMsg (hwnd, WID_RB_FILE, BM_CLICK,
256 MPFROMSHORT (TRUE), PVOID (0));
257 break;
258 case WID_CB_HIDEWINDOW:
259 WinSendDlgItemMsg (hwnd, WID_CB_HIDEWINDOW, BM_CLICK,
260 MPFROMSHORT (TRUE), PVOID (0));
261 break;
262 case WID_CB_DELAYEDCAPTURE:
263 WinSendDlgItemMsg (hwnd, WID_CB_DELAYEDCAPTURE, BM_CLICK,
264 MPFROMSHORT (TRUE), PVOID (0));
265 break;
266
267 case WID_PB_ABOUT:
268 AboutBox (hwnd);
269 break;
270
271 case WID_PB_SETTINGS:
272 pset->Dialog ();
273 break;
274
275 case WID_PB_SCREEN:
276 usCap = CAP_SCREEN;
277 WinSendMsg (hwnd, UM_PREPARECAPTURE, 0,0);
278 break;
279
280 case WID_PB_SCREENREGION:
281 usCap = CAP_SCREENREGION;
282 WinSendMsg (hwnd, UM_PREPARECAPTURE, 0,0);
283 break;
284
285 case WID_PB_WINDOWINTERIOR:
286 usCap = CAP_WINDOWINT;
287 WinSendMsg (hwnd, UM_PREPARECAPTURE, 0,0);
288 break;
289
290 case WID_PB_WINDOW:
291 usCap = CAP_WINDOW;
292 WinSendMsg (hwnd, UM_PREPARECAPTURE, 0,0);
293 break;
294
295 case WID_PB_EXIT:
296 WinSendMsg (hwnd, WM_CLOSE, 0,0);
297 break;
298
299 case HM_HELP_CONTENTS: g_phelp->DisplayContents (); break;
300 case HM_HELP_INDEX: g_phelp->DisplayIndex (); break;
301 case HM_KEYS_HELP: g_phelp->DisplayKeysHelp (); break;
302
303 case HM_GENERAL_HELP:
304 g_phelp->DisplayGeneralHelp ();
305 break;
306
307 default:
308 break;
309 }
310 return MRESULT (FALSE);
311
312 case UM_PREPARECAPTURE:
313 WinSendMsg (hwndSnapshot, UM_STARTCAPTURE, 0,0);
314
315 usState = STATE_WAITFORHIDE;
316 if (WinQueryButtonCheckstate (hwnd, WID_CB_HIDEWINDOW))
317 WinShowWindow (WinQueryWindow (hwnd, QW_PARENT), FALSE);
318 else
319 WinSendMsg (hwnd, UM_WINDOWHIDDEN, 0,0);
320 return MRESULT (FALSE);
321
322 case UM_WINDOWHIDDEN:
323 if (usState == STATE_WAITFORHIDE)
324 {
325 // FIXME
326 // I have no idea why this delay is necessary, but CAP_SCREEN with
327 // hiding our window does not work without it ...
328 _sleep2 (100);
329 usState = STATE_SELECTWINDOW;
330 WinSendMsg (hwnd, UM_SELECTWINDOW, 0,0);
331 }
332 return MRESULT (FALSE);
333
334 case UM_SELECTWINDOW:
335 switch (usCap)
336 {
337 case CAP_SCREEN:
338 usState = STATE_WINDOWSELECTED;
339 WinPostMsg (hwnd, UM_WINDOWSELECTED,
340 MPFROMHWND (HWND_DESKTOP),
341 MPFROMHWND (HWND_DESKTOP));
342 break;
343
344 case CAP_SCREENREGION:
345 if (DoTracking (&rcl))
346 {
347 usState = STATE_WINDOWSELECTED;
348 WinPostMsg (hwnd, UM_WINDOWSELECTED,
349 MPFROMHWND (HWND_DESKTOP),
350 MPFROMHWND (HWND_DESKTOP));
351 }
352 else
353 usState = STATE_IDLE;
354 break;
355
356 case CAP_WINDOWINT:
357 fInterior = TRUE;
358 StartSelection (hwnd);
359 break;
360
361 case CAP_WINDOW:
362 fInterior = FALSE;
363 StartSelection (hwnd);
364 break;
365
366 default:
367 usState = STATE_IDLE;
368 break;
369 }
370 return MRESULT (FALSE);
371
372 case WM_BUTTON1UP:
373 if (usState != STATE_SELECTWINDOW)
374 return MRESULT (FALSE);
375 else
376 {
377 POINTL ptl;
378 WinQueryPointerPos (HWND_DESKTOP, &ptl);
379
380 HWND hwndCapture =
381 WinWindowFromPoint (HWND_DESKTOP, &ptl, FALSE);
382
383 if (hwndCapture && (hwndCapture != HWND_DESKTOP))
384 {
385 HWND hwndOld = hwndCapture;
386
387 if (fInterior)
388 if (! (hwndCapture = WinWindowFromID (hwndOld,
389 FID_CLIENT)))
390 hwndCapture = WinQueryWindow (hwndOld, QW_BOTTOM);
391
392 if (hwndCapture && (hwndCapture != HWND_DESKTOP))
393 {
394 usState = STATE_WINDOWSELECTED;
395 WinPostMsg (hwnd, UM_WINDOWSELECTED,
396 MPFROMHWND (hwndCapture),
397 MPFROMHWND (hwndOld));
398 }
399 else
400 usState = STATE_IDLE;
401 }
402 else
403 usState = STATE_IDLE;
404 }
405 return MRESULT (FALSE);
406
407 case UM_WINDOWSELECTED:
408 if (usState == STATE_WINDOWSELECTED)
409 {
410 // release the pointing device capture if it is active
411 if (WinQueryCapture (HWND_DESKTOP) == hwnd)
412 WinSetCapture (HWND_DESKTOP, NULLHANDLE);
413
414 // reset the pointer to normal shape
415 WinSetPointer (HWND_DESKTOP, WinQuerySysPointer (HWND_DESKTOP,
416 SPTR_ARROW,
417 FALSE));
418 hwndCap = HWND (mp1);
419 hwndParent = HWND (mp2);
420 if (pset->SerialCapture ())
421 {
422 ulTimer = WinStartTimer (hab, hwnd, 1, 49);
423 ulCountdown = pset->QuerySerialTime ();
424 }
425 else if (WinQueryButtonCheckstate (hwnd, WID_CB_DELAYEDCAPTURE))
426 {
427 ulTimer = WinStartTimer (hab, hwnd, 1, 990);
428 ulCountdown = pset->QueryDelayTime ();
429 }
430 else
431 {
432 usState = STATE_CAPTURE;
433 WinPostMsg (hwnd, UM_CAPTURE, 0,0);
434 }
435 }
436 return MRESULT (FALSE);
437
438 case WM_TIMER:
439 ulCountdown --;
440
441 if( ulCountdown % 20 == 0 ) {
442 WinSendMsg (hwndSnapshot, UM_COUNTDOWN, MPFROMLONG (ulCountdown), 0);
443
444 if (pset->DelayCountdown () && !pset->SerialCapture ())
445 DoCountdown (ulCountdown);
446 }
447
448 if (ulCountdown == 0)
449 {
450 WinStopTimer (hab, hwnd, ulTimer);
451 usState = STATE_CAPTURE;
452 WinSendMsg (hwnd, UM_CAPTURE, 0,0);
453 }
454 return MRESULT (FALSE);
455
456 case UM_CAPTURE:
457 usState = STATE_WAITFORHIDE2;
458 if (pset->SSWHide () && WinIsWindowVisible (hwndSnapshot))
459 WinShowWindow (hwndSnapshot, FALSE);
460 else
461 WinSendMsg (hwnd, UM_CAPTURE2, 0,0);
462 return MRESULT (FALSE);
463
464 case UM_SSWHIDDEN:
465 // FIXME
466 // I have no idea why this delay is necessary, but CAP_SCREEN with
467 // hiding our window does not work without it ...
468 _sleep2 (100);
469 WinSendMsg (hwnd, UM_CAPTURE2, 0,0);
470 return MRESULT (FALSE);
471
472 case UM_CAPTURE2:
473 if (usState == STATE_WAITFORHIDE2)
474 {
475 HBITMAP hbm;
476
477 WinEnableWindow (hwnd, FALSE);
478 // capture the window to a bitmap and save this
479 if (usCap == CAP_SCREENREGION)
480 hbm = CaptureWindow (hwndCap, hwndParent, &rcl, TRUE);
481 else
482 hbm = CaptureWindow (hwndCap, hwndParent, NULL, TRUE);
483
484 if (pset->SerialCapture ())
485 {
486 WinStopTimer (hab, hwnd, ulTimer);
487 if (! WinIsWindowVisible (hwndSnapshot) && pset->SnapshotWindow ())
488 WinShowWindow (hwndSnapshot, TRUE);
489
490 if (hbm)
491 {
492 usState = STATE_WINDOWSELECTED;
493 WinPostMsg (hwnd, UM_WINDOWSELECTED,
494 MPFROMHWND (hwndCap),
495 MPFROMHWND (hwndParent));
496 }
497 else
498 WinSendMsg (hwnd, UM_ABORT, 0,0);
499 }
500 else
501 WinSendMsg (hwnd, UM_CLEANUP, 0,0);
502 }
503 return MRESULT (FALSE);
504
505 case UM_ABORT:
506 DosBeep (100, 500);
507 WinSendMsg (hwnd, UM_CLEANUP, 0,0);
508 return MRESULT (FALSE);
509
510 case UM_CLEANUP:
511 if (WinQueryCapture (HWND_DESKTOP) == hwnd)
512 WinSetCapture (HWND_DESKTOP, NULLHANDLE);
513
514 WinSendMsg (hwndSnapshot, UM_STOPCAPTURE, 0,0);
515 WinStopTimer (hab, hwnd, ulTimer);
516
517 // re-show the windows if they are hidden
518 // FIXME using global hwndFrame is pretty yukki
519 if (! WinIsWindowVisible (hwndFrame))
520 WinShowWindow (hwndFrame, TRUE);
521 if (! WinIsWindowVisible (hwndSnapshot) && pset->SnapshotWindow ())
522 WinShowWindow (hwndSnapshot, TRUE);
523
524 WinEnableWindow (hwnd, TRUE);
525 WinSetActiveWindow (HWND_DESKTOP, hwnd);
526 usState = STATE_IDLE;
527 return MRESULT (FALSE);
528 }
529
530#ifdef _DOLOGDEBUG_
531 LogDebug( "MainWin:WindowProcedure:WinDefWindowProc->0x%04x", msg );
532#endif
533 return WinDefWindowProc (hwnd, msg, mp1, mp2);
534}
535
536// ************************************************************************
Note: See TracBrowser for help on using the repository browser.