source: trunk/dll/notify.c@ 907

Last change on this file since 907 was 907, checked in by Steven Levine, 18 years ago

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

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