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