source: trunk/dll/notify.c@ 1394

Last change on this file since 1394 was 1394, checked in by Steven Levine, 17 years ago

Ticket 340: Convert GetPString to use STRINGTABLE.

Drop fm3dll.str and mkstr.exe from makefiles and wpi builders

Convert many functions to expect PCSZ arguments.
Correct walk, compare and dirsizes dialog setups to ignore saved dialog size
Drop copyright.c logic from makefile

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.4 KB
Line 
1/***********************************************************************
2
3 $Id: notify.c 1394 2009-02-05 04:17:25Z stevenhl $
4
5 Thread notes window and popup notification status line
6
7 Copyright (c) 1993-98 M. Kimes
8 Copyright (c) 2006, 2009 Steven H.Levine
9
10 17 Jul 06 SHL Use Win_Error
11 22 Jul 06 SHL Check more run time errors
12 30 Mar 07 GKY Remove GetPString for window class names
13 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
14 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
15 16 Apr 08 SHL Comment and clean up logic
16 10 Dec 08 SHL Integrate exception handler support
17 11 Jan 09 GKY Replace font names in the string file with global set at compile in init.c
18
19***********************************************************************/
20
21#include <stdlib.h>
22#include <string.h>
23#include <ctype.h>
24#include <stddef.h> // _threadid
25// #include <process.h> // _beginthread
26
27#define INCL_DOS
28#define INCL_WIN
29#define INCL_GPI
30#define INCL_LONGLONG // dircnrs.h
31
32#include "fm3dll.h"
33#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
34#include "collect.h" // Data declaration(s)
35#include "grep.h" // Data declaration(s)
36#include "notebook.h" // Data declaration(s)
37#include "init.h" // Data declaration(s)
38#include "fm3dlg.h"
39#include "fm3str.h"
40#include "errutil.h" // Dos_Error...
41#include "strutil.h" // GetPString
42#include "notify.h"
43#include "presparm.h" // SetPresParams
44#include "mainwnd.h" // Data declaration(s)
45#include "wrappers.h" // xmalloc
46#include "misc.h" // PostMsg
47#include "fortify.h"
48#include "excputil.h" // xbeginthread
49
50#pragma data_seg(DATA1)
51
52// Data definitions
53static PSZ pszSrcFile = __FILE__;
54static volatile HWND hwndNotify; // 16 Apr 08 SHL
55
56#pragma data_seg(GLOBAL1)
57BOOL fThreadNotes;
58
59VOID StartNotes(CHAR * s);
60
61/**
62 * Popup notification message window procedure
63 * Display timed message over status line
64 */
65
66MRESULT EXPENTRY NotifyWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
67{
68 static ULONG showing = 0;
69
70 switch (msg) {
71 case WM_CREATE:
72 showing++;
73 {
74 MRESULT rc = PFNWPStatic(hwnd, msg, mp1, mp2);
75
76 if (!WinStartTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER2, 5000)) {
77 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "WinStartTimer");
78 WinDestroyWindow(hwnd);
79 }
80 else {
81
82 RGB2 rgb2F, rgb2;
83
84 memset(&rgb2F, 0, sizeof(RGB2));
85 rgb2F.bRed = (BYTE)65;
86 rgb2.bRed = rgb2.bGreen = rgb2.bBlue = (BYTE)255;
87 rgb2.fcOptions = 0;
88 //fixme to allow user to change presparams 1-10-09 GKY
89 SetPresParams(hwnd, &rgb2, &rgb2F, &rgb2, FNT_8HELVETICA);
90 if (hwndMain) {
91 if (hwndStatus)
92 WinShowWindow(hwndStatus, FALSE);
93 if (hwndStatus2)
94 WinShowWindow(hwndStatus2, FALSE);
95 }
96 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
97 }
98 return rc;
99 }
100
101 case UM_SETUP:
102 WinSetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_SHOW);
103 WinInvalidateRect(hwnd, NULL, FALSE);
104 return 0;
105
106 case WM_SETFOCUS:
107 if (mp2)
108 PostMsg(hwnd, UM_REPLACEFOCUS, mp1, MPVOID);
109 break;
110
111 case UM_REPLACEFOCUS:
112 if (mp1)
113 WinSetFocus(HWND_DESKTOP, (HWND) mp1);
114 PostMsg(hwnd, UM_SETUP, MPVOID, MPVOID);
115 return 0;
116
117 case WM_PAINT:
118 {
119 SWP swp;
120 POINTL ptl;
121
122 MRESULT mr = PFNWPStatic(hwnd, msg, mp1, mp2);
123 HPS hps = WinGetPS(hwnd);
124 if (hps) {
125 if (WinQueryWindowPos(hwnd, &swp)) {
126 ptl.x = 0;
127 ptl.y = 0;
128 GpiMove(hps, &ptl);
129 GpiSetColor(hps, CLR_RED);
130 ptl.x = swp.cx - 1;
131 ptl.y = swp.cy - 1;
132 GpiBox(hps, DRO_OUTLINE, &ptl, 2, 2);
133 }
134 WinReleasePS(hwnd);
135 }
136 return mr;
137 }
138
139 case WM_BUTTON1DOWN:
140 case WM_BUTTON2DOWN:
141 case WM_BUTTON3DOWN:
142 case WM_TIMER:
143 case WM_CLOSE:
144 WinStopTimer(WinQueryAnchorBlock(hwnd), hwnd, ID_TIMER2);
145 WinDestroyWindow(hwnd);
146 return 0;
147
148 case WM_DESTROY:
149 showing--;
150 if (!showing && hwndMain) {
151 if (hwndStatus)
152 WinShowWindow(hwndStatus, TRUE);
153 if (hwndStatus2)
154 WinShowWindow(hwndStatus2, TRUE);
155 }
156 break;
157 }
158 return PFNWPStatic(hwnd, msg, mp1, mp2);
159}
160
161/**
162 * Display timed notification window over status line
163 */
164
165HWND DoNotify(PCSZ str)
166{
167 char *p;
168 HWND hwnd = (HWND) 0, hwndP;
169 LONG x, y, cx, cy;
170 SWP swp, swpS, swpS2;
171 static USHORT id = NOTE_FRAME;
172
173 if (str && *str) {
174 // figure out what size the window should be and where it should be
175 hwndP = hwndMain ? WinQueryWindow(hwndMain, QW_PARENT) : HWND_DESKTOP;
176 WinQueryWindowPos(hwndP, &swp);
177 if (hwndStatus)
178 WinQueryWindowPos(hwndStatus, &swpS);
179 if (hwndStatus2)
180 WinQueryWindowPos(hwndStatus2, &swpS2);
181 x = hwndMain ? (hwndStatus ? swpS.x - 1 :
182 WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)) : 0;
183 y = hwndMain ? (hwndStatus ? swpS.y - 1 :
184 WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)) : 0;
185 if (hwndMain && hwndStatus) {
186 if (hwndStatus2)
187 cx = swpS2.cx + swpS.cx + 8;
188 else
189 cx = swpS.cx + 6;
190 }
191 else
192 cx = (swp.cx - ((x * 2) + 4));
193 cy = hwndMain ? (hwndStatus ? swpS.cy + 2 : 28) : 28;
194
195 // pretty-up the note by putting on a leading space
196 if (*str != ' ') {
197 p = xmalloc(strlen(str) + 2, pszSrcFile, __LINE__);
198 if (!p)
199 p = (PSZ)str;
200 else {
201 strcpy(p + 1, str);
202 *p = ' ';
203 }
204 }
205 else
206 p = (PSZ)str;
207
208 hwnd = WinCreateWindow(hwndP,
209 WC_ERRORWND,
210 p,
211 SS_TEXT | DT_LEFT | DT_VCENTER | WS_VISIBLE,
212 x, y, cx, cy, hwndP, HWND_TOP, id++, NULL, NULL);
213 if (!hwndP)
214 Win_Error2(hwndP, hwndP, pszSrcFile, __LINE__, IDS_WINCREATEWINDOW);
215
216 if (p != str)
217 free(p);
218 if (id > NOTE_MAX)
219 id = NOTE_FRAME;
220 }
221
222 AddNote(str);
223
224 return hwnd;
225}
226
227/**
228 * Add message to thread notes window
229 */
230
231HWND Notify(PCSZ str)
232{
233 return (HWND)WinSendMsg(MainObjectHwnd, UM_NOTIFY, MPFROMP(str), MPVOID);
234}
235
236/**
237 * Add error message to thread notes window
238 */
239
240VOID NotifyError(PCSZ filename, APIRET status)
241{
242 CHAR errortext[512];
243
244 if (!filename)
245 return;
246 sprintf(errortext, GetPString(IDS_ERRORACCESSTEXT), status, filename);
247 if (toupper(*filename) > 'B') {
248 if (status == 21)
249 strcat(errortext, GetPString(IDS_EMPTYREMOVETEXT));
250 else if (status == 27)
251 strcat(errortext, GetPString(IDS_CDMUSICTEXT));
252 else if (status == 19)
253 strcat(errortext, GetPString(IDS_WRITEPROTECTTEXT));
254 else if (status == 108)
255 strcat(errortext, GetPString(IDS_DRIVELOCKEDTEXT));
256 }
257 else {
258 if (status == 21)
259 strcat(errortext, GetPString(IDS_EMPTYFLOPPYTEXT));
260 else if (status == 27)
261 strcat(errortext, GetPString(IDS_UNFORMATEDTEXT));
262 else if (status == 107)
263 sprintf(&errortext[strlen(errortext)],
264 GetPString(IDS_PHANTOMTEXT), toupper(*filename));
265 else if (status == 19)
266 strcat(errortext, GetPString(IDS_DISKWRITEPROTEXTTEXT));
267 else if (status == 108)
268 strcat(errortext, GetPString(IDS_DISKLOCKEDTEXT));
269 }
270 DosBeep(250, 10);
271 DosBeep(500, 10);
272 DosBeep(250, 10);
273 DosBeep(500, 10);
274 Notify(errortext);
275}
276
277/**
278 * Thread notes dialog window dialog procedure
279 */
280
281MRESULT EXPENTRY NoteWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
282{
283 static HPOINTER hptrIcon = (HPOINTER) 0;
284
285 switch (msg) {
286 case WM_INITDLG:
287 if (hwndNotify != (HWND)0) {
288 // Already have notes dialog - pass message on
289 if (mp2) {
290 WinSendDlgItemMsg(hwndNotify,
291 NOTE_LISTBOX,
292 LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0), mp2);
293 PostMsg(hwndNotify, UM_NOTIFY, MPVOID, MPVOID);
294 free((CHAR *)mp2);
295 }
296 WinDismissDlg(hwnd, 0);
297 break;
298 }
299 hwndNotify = hwnd;
300 fThreadNotes = FALSE;
301 // Remember showing
302 {
303 BOOL dummy = TRUE;
304 PrfWriteProfileData(fmprof,
305 FM3Str, "ThreadNotes", &dummy, sizeof(BOOL));
306 }
307 if (mp2) {
308 WinSendDlgItemMsg(hwnd,
309 NOTE_LISTBOX,
310 LM_INSERTITEM, MPFROM2SHORT(LIT_END, 0), mp2);
311 free((CHAR *)mp2);
312 }
313
314 {
315 // Return focus
316 HWND hwndActive = WinQueryActiveWindow(HWND_DESKTOP);
317 PostMsg(hwnd, UM_FOCUSME, MPFROMLONG(hwndActive), MPVOID);
318 }
319
320 hptrIcon = WinLoadPointer(HWND_DESKTOP, FM3ModHandle, NOTE_FRAME);
321 if (hptrIcon)
322 WinDefDlgProc(hwnd, WM_SETICON, MPFROMLONG(hptrIcon), MPFROMLONG(0L));
323 break;
324
325 case UM_FOCUSME:
326 {
327 ULONG size = sizeof(SWP),
328 fl = SWP_ZORDER | SWP_FOCUSDEACTIVATE | SWP_SHOW;
329 SWP swp;
330
331 if (PrfQueryProfileData(fmprof,
332 FM3Str, "NoteWndSwp", (PVOID) & swp, &size)) {
333 if (swp.fl & (SWP_HIDE | SWP_MINIMIZE)) {
334 fl |= SWP_MINIMIZE;
335 fl &= (~SWP_SHOW);
336 }
337 else
338 fl |= (SWP_MOVE | SWP_SIZE);
339 }
340 WinSetWindowPos(hwnd, HWND_BOTTOM, swp.x, swp.y, swp.cx, swp.cy, fl);
341 if (fl & SWP_MINIMIZE) {
342 WinSetWindowUShort(hwnd, QWS_XRESTORE, (USHORT) swp.x);
343 WinSetWindowUShort(hwnd, QWS_CXRESTORE, (USHORT) swp.cx);
344 WinSetWindowUShort(hwnd, QWS_YRESTORE, (USHORT) swp.y);
345 WinSetWindowUShort(hwnd, QWS_CYRESTORE, (USHORT) swp.cy);
346 }
347 }
348 if (mp1)
349 WinSetActiveWindow(HWND_DESKTOP, (HWND) mp1);
350 return 0;
351
352 case UM_STRETCH:
353 {
354 SWP swp;
355 LONG titl, szbx, szby;
356
357 WinQueryWindowPos(hwnd, &swp);
358 if (!(swp.fl & (SWP_MINIMIZE | SWP_HIDE))) {
359 szbx = SysVal(SV_CXSIZEBORDER);
360 szby = SysVal(SV_CYSIZEBORDER);
361 titl = SysVal(SV_CYTITLEBAR);
362 WinSetWindowPos(WinWindowFromID(hwnd, NOTE_LISTBOX),
363 HWND_TOP,
364 szbx,
365 szby,
366 swp.cx - (szbx * 2L),
367 (swp.cy - titl) - (szby * 2L), SWP_MOVE | SWP_SIZE);
368 }
369 if (!(swp.fl & SWP_MAXIMIZE)) {
370 if (swp.fl & (SWP_MINIMIZE | SWP_HIDE)) {
371 swp.x = WinQueryWindowUShort(hwnd, QWS_XRESTORE);
372 swp.y = WinQueryWindowUShort(hwnd, QWS_YRESTORE);
373 swp.cx = WinQueryWindowUShort(hwnd, QWS_CXRESTORE);
374 swp.cy = WinQueryWindowUShort(hwnd, QWS_CYRESTORE);
375 }
376 PrfWriteProfileData(fmprof,
377 FM3Str, "NoteWndSwp", (PVOID) & swp, sizeof(SWP));
378 }
379 }
380 return 0;
381
382 case WM_ADJUSTWINDOWPOS:
383 PostMsg(hwnd, UM_STRETCH, MPVOID, MPVOID);
384 break;
385
386 case UM_CONTAINER_FILLED:
387 {
388 SHORT y;
389 SHORT x = (SHORT)WinSendDlgItemMsg(hwnd,
390 NOTE_LISTBOX,
391 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
392 if (x > 60) {
393 for (y = 0; y < x - 50; y++) {
394 WinSendDlgItemMsg(hwnd,
395 NOTE_LISTBOX,
396 LM_DELETEITEM, MPFROMSHORT(y), MPVOID);
397 }
398 }
399 }
400 return 0;
401
402 case UM_NOTIFY:
403 {
404 SHORT x = (SHORT) WinSendDlgItemMsg(hwnd,
405 NOTE_LISTBOX,
406 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
407 if (x > 0)
408 WinSendDlgItemMsg(hwnd,
409 NOTE_LISTBOX,
410 LM_SETTOPINDEX, MPFROMSHORT(x), MPVOID);
411 }
412 return 0;
413
414 case UM_SHOWME:
415 WinSetWindowPos(hwnd,
416 HWND_TOP,
417 0,
418 0,
419 0, 0, SWP_SHOW | SWP_RESTORE | SWP_ZORDER | SWP_ACTIVATE);
420 return 0;
421
422 case WM_COMMAND:
423 return 0;
424
425 case WM_CLOSE:
426 WinDismissDlg(hwnd, 0);
427 return 0;
428
429 case WM_DESTROY:
430 if (hwndNotify == hwnd) {
431 fThreadNotes = FALSE;
432 PrfWriteProfileData(fmprof,
433 FM3Str, "ThreadNotes", &fThreadNotes, sizeof(BOOL));
434 hwndNotify = (HWND) 0;
435 }
436 if (hptrIcon)
437 WinDestroyPointer(hptrIcon);
438 if (!PostMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID))
439 WinSendMsg((HWND) 0, WM_QUIT, MPVOID, MPVOID);
440 break;
441 }
442 return WinDefDlgProc(hwnd, msg, mp1, mp2);
443}
444
445/**
446 * Thread notes dialog window thread
447 */
448
449static VOID NoteThread(VOID * args)
450{
451 HAB hab = WinInitialize(0);
452# ifdef FORTIFY
453 Fortify_EnterScope();
454# endif
455 if (hab) {
456 HMQ hmq = WinCreateMsgQueue(hab, 0);
457 if (hmq) {
458 if (!hwndNotify)
459 WinDlgBox(HWND_DESKTOP,
460 HWND_DESKTOP,
461 NoteWndProc, FM3ModHandle, NOTE_FRAME, (CHAR *)args);
462 WinDestroyMsgQueue(hmq);
463 }
464 WinTerminate(hab);
465 }
466# ifdef FORTIFY
467 Fortify_LeaveScope();
468# endif
469}
470
471/**
472 * Start thread notes dialog window thread
473 */
474
475VOID StartNotes(CHAR * note)
476{
477 if (!hwndNotify) {
478 if (xbeginthread(NoteThread,
479 65536,
480 note,
481 pszSrcFile,
482 __LINE__) != -1)
483 {
484 USHORT i;
485 for (i = 0; !hwndNotify && i < 10; i++)
486 DosSleep(10);
487 if (!hwndNotify)
488 Runtime_Error(pszSrcFile, __LINE__, "Can not create Notify window");
489 }
490 }
491}
492
493/**
494 * Add note to thread notes window or popup status window
495 */
496
497BOOL AddNote(PCSZ note)
498{
499 PSZ s;
500 PCSZ p;
501 BOOL once = FALSE, ret = FALSE;
502
503 if ((fThreadNotes || hwndNotify) && note && *note) {
504 p = note;
505 while (*p == ' ')
506 p++;
507 if (*p) {
508 if (!hwndNotify) {
509 fThreadNotes = FALSE;
510 StartNotes(NULL);
511 }
512 if (hwndNotify) {
513 s = xmalloc(strlen(p) + 14, pszSrcFile, __LINE__);
514 if (s) {
515 sprintf(s, "%08lx %s", _threadid, p);
516 while (!once) {
517 if ((SHORT) WinSendDlgItemMsg(hwndNotify,
518 NOTE_LISTBOX,
519 LM_INSERTITEM,
520 MPFROM2SHORT(LIT_END, 0),
521 MPFROMP(s)) >= 0) {
522 ret = TRUE;
523 PostMsg(hwndNotify, UM_NOTIFY, MPVOID, MPVOID);
524 break;
525 }
526 PostMsg(hwndNotify, UM_CONTAINER_FILLED, MPVOID, MPVOID);
527 once = TRUE;
528 }
529 free(s);
530 }
531 }
532 }
533 }
534 return ret;
535}
536
537/**
538 * Close thread notes window
539 */
540
541VOID EndNote(VOID)
542{
543 if (hwndNotify)
544 if (!PostMsg(hwndNotify, WM_CLOSE, MPVOID, MPVOID))
545 WinSendMsg(hwndNotify, WM_CLOSE, MPVOID, MPVOID);
546}
547
548/**
549 * Pop up thread notes window
550 */
551
552VOID ShowNote(VOID)
553{
554 if (!hwndNotify)
555 StartNotes(NULL);
556 if (hwndNotify)
557 PostMsg(hwndNotify, UM_SHOWME, MPVOID, MPVOID);
558}
559
560/**
561 * Hide thread notes window
562 */
563
564VOID HideNote(VOID)
565{
566 if (hwndNotify)
567 WinSetWindowPos(hwndNotify,
568 HWND_BOTTOM,
569 0,
570 0, 0, 0, SWP_MINIMIZE | SWP_ZORDER | SWP_FOCUSDEACTIVATE);
571}
572
573#pragma alloc_text(NOTIFY,Notify,NotifyWndProc,StartNotify,NotifyError)
574#pragma alloc_text(NOTIFY2,AddNote,NoteThread,NoteWndProc)
575#pragma alloc_text(NOTIFY3,StartNotes,EndNote,HideNote,ShowNote)
Note: See TracBrowser for help on using the repository browser.