5ec71092dfb80168f2fa4b3827ceca5d4cc48c4d
[openafs.git] / src / WINNT / client_exp / msgs.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include "stdafx.h"
11 #include <winsock2.h>
12 #include <ws2tcpip.h>
13
14 extern "C" {
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 }
18
19 #include <tchar.h>
20 #include <stdarg.h>
21
22 #include "msgs.h"
23
24
25
26 /* 
27   ShowMessageBox:
28
29   This function takes three main arguements, the stringtable ID, the button types
30   to be displayed (default = MB_OK) and the help table reference (default = 0, no 
31   help) and then a variable amount of arguements. The variable list does not need 
32   a special ending flag/character/number. The list is read only as needed, which 
33   is defined by the string table and the presence of any "%X" characters, where X 
34   is one of the printf format types. The order of the variable list MUST 
35   correspond to the order of types in the string table entry. If the string table 
36   calls for INT INT UINT CHAR* DOUBLE, then the arguement list had better be INT 
37   INT UINT CHAR* DOUBLE or else there will be serious problems (stack will be 
38   misread, general protection faults, garbage output, and other errors).
39
40   This function takes the arguements passed in the list and inserts them by 
41   parsing and pszcut/pszpaste the string table entry to add all the arguements passed 
42   in. This allows for any generic       message to be created.
43
44   %i,d    = Integer
45   %u      = unsigned int
46   %x,X    = Hex (takes an integer arguement, pszconverts it)
47   %g,f,e  = Double
48   %s      = String (char*)
49   %l
50   d       = Long int
51   x       = long hex
52   %c      = character (one)
53   %a      = String Table Ref. (UINT)
54   %o      = CString object (prints the string of the object)
55   default = prints out string so far, with error message attached at place of error.
56
57   Return type is the button pressed in the message box.
58  
59 */
60
61 UINT ShowMessageBox (UINT Id, UINT Button, UINT Help, ...) {
62
63     CString temp;
64     TCHAR *pszstring, 
65     *pszpaste, 
66     *pszcut, 
67     *pszdone,
68     *pszconvert;
69     TCHAR chread;
70     va_list params;
71     int x;
72
73     pszconvert = new TCHAR[255];        
74     va_start(params, Help);
75     LoadString (temp, Id);
76     pszstring = temp.GetBuffer(512);
77     _tcscpy(pszstring,pszstring);
78     temp.ReleaseBuffer();
79     // Look and see - is there a need to insert chars (95% of the time, there won't)
80     if (!_tcsstr(pszstring, _T("%"))) {
81         delete pszconvert;
82         return AfxMessageBox(pszstring, Button, Help);
83     }   
84
85     x = _tcscspn(pszstring, _T("%"));
86     pszdone = new TCHAR[512];
87     pszcut = new TCHAR[512];
88     pszpaste = new TCHAR[512];
89     _tcscpy(pszcut, &pszstring[x+2]);
90     _tcsncpy(pszpaste, pszstring, x);
91     pszpaste[x] = _T('\0');
92     chread = pszstring[x+1];
93
94     for ( ; ; ) {
95
96         switch (chread) { 
97         case    _T('i') :
98         case    _T('d') :
99         {           
100             int anint = va_arg(params, int);
101             _itot( anint, pszconvert, 10);
102             break;
103         }
104         case    _T('u') :
105         {       
106             UINT anuint = va_arg(params, UINT);
107             _itot( anuint, pszconvert, 10);
108             break;
109         }
110
111         case    _T('x') :
112         case    _T('X') :   
113         {
114             int ahex = va_arg(params, int);
115             _itot( ahex, pszconvert, 16);
116             break;
117         }
118         case    _T('g') :
119         case    _T('f') :
120         case    _T('e') :   
121         {
122             double adbl = va_arg(params, double);
123             _stprintf(pszconvert, _T("%g"), adbl);
124             break;
125         }
126         case    _T('s') :       
127         {
128             TCHAR *pStr = va_arg(params, TCHAR*);
129             ASSERT(_tcslen(pStr) <= 255);
130             _tcscpy(pszconvert, pStr);
131             break;
132         }
133         case    _T('l') :       
134         {
135             chread = pszdone[x+2];
136             switch(chread) {
137             case        _T('x') :
138             {
139                 long int alhex = va_arg(params, long int);
140                 _ltot(alhex, pszconvert, 16);
141                 _tcscpy(pszcut, &pszcut[1]);
142                 break;
143             }
144             case        _T('d') :
145                 default         :
146                 {
147                     long int along = va_arg(params, long int);
148                     _ltot( along, pszconvert, 10);
149                     // For the L, there will be one character after it,
150                     //   so move ahead another letter
151                     _tcscpy(pszcut, &pszcut[1]);
152                     break;
153                 }
154             }
155             break;
156         }
157
158         case    _T('c') :       
159         {
160             int letter = va_arg(params, int);
161             pszconvert[0] = (TCHAR)letter;
162             pszconvert[1] = '\0'; 
163             break;
164         }
165         case    _T('a') :
166         {
167             CString zeta;
168             TCHAR* lsc;
169             UINT ls = va_arg(params, UINT);
170             LoadString (zeta, ls);
171             lsc = zeta.GetBuffer(255);
172             _tcscpy(pszconvert, lsc);
173             zeta.ReleaseBuffer();
174             break;
175         }
176         case    _T('o') :
177         {
178             CString get = va_arg(params, CString);
179             TCHAR* ex = get.GetBuffer(255);
180             _tcscpy(pszconvert,ex);
181             get.ReleaseBuffer();
182             break;
183         }
184             default     :
185             {   
186                 _tcscpy(pszconvert, _T(" Could not load message. Invalid %type in string table entry. "));
187                 delete pszdone;
188                 pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
189                 _tcscpy(pszdone, pszpaste);
190                 _tcscat(pszdone, pszconvert);
191                 _tcscat(pszdone, pszcut);
192                 AfxMessageBox(pszdone, Button, Help);
193                 delete pszcut;
194                 delete pszpaste;
195                 delete pszconvert;
196                 delete pszdone;
197                 ASSERT(FALSE);
198                 return 0;
199             }           
200         } // case
201
202         delete pszdone;
203         pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
204         _tcscpy(pszdone, pszpaste);
205         _tcscat(pszdone, pszconvert);
206         _tcscat(pszdone, pszcut);
207         // Now pszdone holds the entire message.
208         // Check to see if there are more insertions to be made or not
209         
210         if (!_tcsstr(pszdone, _T("%"))) {
211             UINT rt_type = AfxMessageBox(pszdone, Button, Help);
212             delete pszcut;
213             delete pszpaste;
214             delete pszconvert;
215             delete pszdone;
216             return rt_type;
217         } // if
218
219         // there are more insertions to make, prepare the strings to use.
220         x = _tcscspn(pszdone, _T("%"));
221         _tcscpy(pszcut, &pszdone[x+2]);
222         _tcsncpy(pszpaste, pszdone, x); 
223         pszpaste[x] = _T('\0');
224         chread = pszdone[x+1];
225         
226     } // for
227     ASSERT(FALSE);              
228     return 0;
229
230 } // ShowMessageBox
231
232 CString GetMessageString(UINT Id, ...)
233 {
234     CString temp;
235     TCHAR *pszstring, 
236     *pszpaste, 
237     *pszcut, 
238     *pszdone,
239     *pszconvert;
240     TCHAR chread;
241     va_list params;
242     int x;
243     CString strMsg;
244
245     pszconvert = new TCHAR[255];        
246     va_start(params, Id);
247     LoadString (temp, Id);
248     pszstring = temp.GetBuffer(512);
249     _tcscpy(pszconvert,pszstring);
250     temp.ReleaseBuffer();
251
252     // Look and see - is there a need to insert chars (95% of the time, there won't)
253     if (!_tcsstr(pszstring, _T("%"))) {
254         strMsg = pszconvert;
255         delete pszconvert;
256         return strMsg;
257     }   
258
259     x = _tcscspn(pszstring, _T("%"));
260     pszdone = new TCHAR[512];
261     pszcut = new TCHAR[512];
262     pszpaste = new TCHAR[512];
263     _tcscpy(pszcut, &pszstring[x+2]);
264     _tcsncpy(pszpaste, pszstring, x);
265     pszpaste[x] = _T('\0');
266     chread = pszstring[x+1];
267
268     for ( ; ; ) {
269
270         switch (chread) { 
271         case    _T('i') :
272         case    _T('d') :
273         {           
274             int anint = va_arg(params, int);
275             _itot( anint, pszconvert, 10);
276             break;
277         }
278         case    _T('u') :
279         {       
280             UINT anuint = va_arg(params, UINT);
281             _itot( anuint, pszconvert, 10);
282             break;
283         }
284
285         case    _T('x') :
286         case    _T('X') :   
287         {
288             int ahex = va_arg(params, int);
289             _itot( ahex, pszconvert, 16);
290             break;
291         }
292         case    _T('g') :
293         case    _T('f') :
294         case    _T('e') :   
295         {
296             double adbl = va_arg(params, double);
297             _stprintf(pszconvert, _T("%g"), adbl);
298             break;
299         }
300         case    _T('s') :       
301         {
302             TCHAR *pStr = va_arg(params, TCHAR*);
303             ASSERT(_tcslen(pStr) <= 255);
304             _tcscpy(pszconvert, pStr);
305             break;
306         }
307         case    _T('l') :       
308         {
309             chread = pszdone[x+2];
310             switch(chread) {
311             case        _T('x') :
312             {
313                 long int alhex = va_arg(params, long int);
314                 _ltot(alhex, pszconvert, 16);
315                 _tcscpy(pszcut, &pszcut[1]);
316                 break;
317             }
318             case        _T('d') :
319                 default         :
320                 {
321                     long int along = va_arg(params, long int);
322                     _ltot( along, pszconvert, 10);
323                     // For the L, there will be one character after it,
324                     //   so move ahead another letter
325                     _tcscpy(pszcut, &pszcut[1]);
326                     break;
327                 }
328             }
329             break;
330         }       
331
332         case    _T('c') :       
333         {
334             int letter = va_arg(params, int);
335             pszconvert[0] = (TCHAR)letter;
336             pszconvert[1] = _T('\0'); 
337             break;
338         }
339         case    _T('a') :
340         {
341             CString zeta;
342             TCHAR* lsc;
343             UINT ls = va_arg(params, UINT);
344             LoadString (zeta, ls);
345             lsc = zeta.GetBuffer(255);
346             _tcscpy(pszconvert, lsc);
347             zeta.ReleaseBuffer();
348             break;
349         }
350         case    _T('o') :
351         {
352             CString get = va_arg(params, CString);
353             TCHAR* ex = get.GetBuffer(255);
354             _tcscpy(pszconvert,ex);
355             get.ReleaseBuffer();
356             break;
357         }
358         default:
359             {   
360                 _tcscpy(pszconvert, _T(" Could not load message. Invalid %type in string table entry. "));
361                 delete pszdone;
362                 pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
363                 _tcscpy(pszdone, pszpaste);
364                 _tcscat(pszdone, pszconvert);
365                 _tcscat(pszdone, pszcut);
366                 strMsg = pszdone;
367                 delete pszcut;
368                 delete pszpaste;
369                 delete pszconvert;
370                 delete pszdone;
371                 ASSERT(FALSE);
372                 return strMsg;
373             }           
374         } // case
375
376         delete pszdone;
377         pszdone = new TCHAR[_tcslen(pszpaste)+_tcslen(pszcut)+_tcslen(pszconvert)+5];
378         _tcscpy(pszdone, pszpaste);
379         _tcscat(pszdone, pszconvert);
380         _tcscat(pszdone, pszcut);
381         // Now pszdone holds the entire message.
382         // Check to see if there are more insertions to be made or not
383         
384         if (!_tcsstr(pszdone, _T("%"))) {
385             strMsg = pszdone;
386             delete pszcut;
387             delete pszpaste;
388             delete pszconvert;
389             delete pszdone;
390             return strMsg;
391         } // if
392
393         // there are more insertions to make, prepare the strings to use.
394         x = _tcscspn(pszdone, _T("%"));
395         _tcscpy(pszcut, &pszdone[x+2]);
396         _tcsncpy(pszpaste, pszdone, x); 
397         pszpaste[x] = _T('\0');
398         chread = pszdone[x+1];
399         
400     } // for
401     ASSERT(FALSE);              
402     return strMsg;
403 }
404
405 void LoadString (CString &Str, UINT id)
406 {
407     extern EXPORTED void GetString (LPSTR pszTarget, int idsSource, int cchMax = cchRESOURCE);
408
409     char szString[ 256 ];
410     GetString (szString, id);
411 #ifdef UNICODE
412     CString wstr(szString);
413     Str = wstr;
414 #else
415     Str = szString;
416 #endif
417 }
418