source: trunk/dll/notify.c@ 985

Last change on this file since 985 was 985, checked in by Gregg Young, 18 years ago

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

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