windows-64-bit-type-safety-20051105
[openafs.git] / src / WINNT / afsusrmgr / display.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 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include "TaAfsUsrMgr.h"
16 #include "usr_col.h"
17 #include "grp_col.h"
18 #include "mch_col.h"
19
20
21 /*
22  * ANIMATED ICON ______________________________________________________________
23  *
24  */
25
26 static DWORD l_cReqAnimation = 0;
27
28 void Display_StartWorking (void)
29 {
30    if ((++l_cReqAnimation) == 1)
31       {
32       AfsAppLib_StartAnimation (GetDlgItem (g.hMain, IDC_ANIM));
33       }
34 }
35
36
37 void Display_StopWorking (void)
38 {
39    if (!l_cReqAnimation || !(--l_cReqAnimation))
40       {
41       AfsAppLib_StopAnimation (GetDlgItem (g.hMain, IDC_ANIM));
42       }
43 }
44
45
46 /*
47  * USER/GROUP LISTS ___________________________________________________________
48  *
49  */
50
51 void Display_PopulateList (void)
52 {
53    switch (Display_GetActiveTab())
54       {
55       case ttUSERS:
56          Display_PopulateUserList();
57          break;
58
59       case ttGROUPS:
60          Display_PopulateGroupList();
61          break;
62
63       case ttMACHINES:
64          Display_PopulateMachineList();
65          break;
66       }
67 }
68
69
70 void Display_PopulateUserList (void)
71 {
72    if (g.idCell)
73       {
74       HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
75       HWND hList = GetDlgItem (hDlg, IDC_USERS_LIST);
76       if (IsWindow (hList))
77          {
78          TCHAR szQuerying[ cchRESOURCE ];
79          GetString (szQuerying, IDS_QUERYING_LONG);
80          SetDlgItemText (hDlg, IDC_USERS_TITLE, szQuerying);
81
82          Display_StartWorking();
83          GetDlgItemText (hDlg, IDC_USERS_PATTERN, g.szPatternUsers, cchNAME);
84          StartTask (taskUPD_USERS, g.hMain);
85          }
86       }
87 }
88
89
90 void Display_PopulateGroupList (void)
91 {
92    if (g.idCell)
93       {
94       HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
95       HWND hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
96       if (IsWindow (hList))
97          {
98          TCHAR szQuerying[ cchRESOURCE ];
99          GetString (szQuerying, IDS_QUERYING_LONG);
100          SetDlgItemText (hDlg, IDC_GROUPS_TITLE, szQuerying);
101
102          Display_StartWorking();
103          GetDlgItemText (hDlg, IDC_GROUPS_PATTERN, g.szPatternGroups, cchNAME);
104          StartTask (taskUPD_GROUPS, g.hMain);
105          }
106       }
107 }
108
109
110 void Display_PopulateMachineList (void)
111 {
112    if (g.idCell)
113       {
114       HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
115       HWND hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
116       if (IsWindow (hList))
117          {
118          TCHAR szQuerying[ cchRESOURCE ];
119          GetString (szQuerying, IDS_QUERYING_LONG);
120          SetDlgItemText (hDlg, IDC_MACHINES_TITLE, szQuerying);
121
122          Display_StartWorking();
123          GetDlgItemText (hDlg, IDC_MACHINES_PATTERN, g.szPatternMachines, cchNAME);
124          StartTask (taskUPD_MACHINES, g.hMain);
125          }
126       }
127 }
128
129
130 void Display_OnEndTask_UpdUsers (LPTASKPACKET ptp)
131 {
132    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
133    HWND hList = GetDlgItem (hDlg, IDC_USERS_LIST);
134    if (IsWindow (hList) && !lstrcmpi (TASKDATA(ptp)->szPattern, g.szPatternUsers))
135       {
136       FastList_Begin (hList);
137
138       // Update the title above the list to indicate what we're showing
139       //
140       TCHAR szCell[ cchRESOURCE ];
141       asc_CellNameGet_Fast (g.idClient, g.idCell, szCell);
142
143       LPTSTR pszTitle = FormatString ((TASKDATA(ptp)->szPattern[0] || (gr.SearchUsers.SearchType != SEARCH_NO_LIMITATIONS)) ? IDS_USERS_PATTERN : IDS_USERS_ALL, TEXT("%s"), szCell);
144       SetDlgItemText (hDlg, IDC_USERS_TITLE, pszTitle);
145       FreeString (pszTitle);
146
147       // For faster access, we'll want to use a hashlist to deal with
148       // the items in our ASIDLIST (right now it's just a flat array).
149       // This lets us remove duplicates--which is no big deal because
150       // there shouldn't be any anyway--but more importantly it lets
151       // us instantly determine if a particular ASID is in the list
152       // (the asc_AsidListTest function is O(n), and we need O(1)).
153       //
154       LPHASHLIST pAsidList = New (HASHLIST);
155       if (TASKDATA(ptp)->pAsidList)
156          {
157          for (size_t iAsid = 0; iAsid < TASKDATA(ptp)->pAsidList->cEntries; ++iAsid)
158             pAsidList->AddUnique ((PVOID)(TASKDATA(ptp)->pAsidList->aEntries[ iAsid ].idObject));
159          }
160
161       // Delete any items which are currently in the FastList but
162       // which aren't in our AsidList.
163       //
164       HLISTITEM hItemNext;
165       for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = hItemNext)
166          {
167          hItemNext = FastList_FindNext (hList, hItem);
168          ASID idObject = (ASID)FastList_GetItemParam (hList, hItem);
169          if (!pAsidList->fIsInList ((PVOID)idObject))
170             FastList_RemoveItem (hList, hItem);
171          }
172
173       // Add items for any entries which are in our AsidList but aren't
174       // currently in the FastList.
175       //
176       DWORD dwStyle = GetWindowLong (hList, GWL_STYLE);
177
178       for (LPENUM pEnum = pAsidList->FindFirst(); pEnum; pEnum = pEnum->FindNext())
179          {
180          ASID idObject = (ASID)( pEnum->GetObject() );
181
182          HLISTITEM hItem;
183          if ((hItem = FastList_FindItem (hList, (LPARAM)idObject)) == NULL)
184             {
185             FASTLISTADDITEM ai;
186             memset (&ai, 0x00, sizeof(ai));
187             Display_GetImageIcons (dwStyle, gr.ivUsr, idObject, imageUSER, IMAGE_NOIMAGE, &ai.iFirstImage, &ai.iSecondImage);
188             ai.lParam = (LPARAM)idObject;
189             hItem = FastList_AddItem (hList, &ai);
190             }
191          }
192
193       Delete (pAsidList);
194       FastList_End (hList);
195       }
196
197    Display_StopWorking();
198 }
199
200
201 void Display_OnEndTask_UpdGroups (LPTASKPACKET ptp)
202 {
203    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
204    HWND hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
205    if (IsWindow (hList) && !lstrcmpi (TASKDATA(ptp)->szPattern, g.szPatternGroups))
206       {
207       FastList_Begin (hList);
208
209       // Update the title above the list to indicate what we're showing
210       //
211       TCHAR szCell[ cchRESOURCE ];
212       asc_CellNameGet_Fast (g.idClient, g.idCell, szCell);
213
214       LPTSTR pszTitle = FormatString ((TASKDATA(ptp)->szPattern[0]) ? IDS_GROUPS_PATTERN : IDS_GROUPS_ALL, TEXT("%s"), szCell);
215       SetDlgItemText (hDlg, IDC_GROUPS_TITLE, pszTitle);
216       FreeString (pszTitle);
217
218       // For faster access, we'll want to use a hashlist to deal with
219       // the items in our ASIDLIST (right now it's just a flat array).
220       // This lets us remove duplicates--which is no big deal because
221       // there shouldn't be any anyway--but more importantly it lets
222       // us instantly determine if a particular ASID is in the list
223       // (the asc_AsidListTest function is O(n), and we need O(1)).
224       //
225       LPHASHLIST pAsidList = New (HASHLIST);
226       if (TASKDATA(ptp)->pAsidList)
227          {
228          for (size_t iAsid = 0; iAsid < TASKDATA(ptp)->pAsidList->cEntries; ++iAsid)
229             pAsidList->AddUnique ((PVOID)(TASKDATA(ptp)->pAsidList->aEntries[ iAsid ].idObject));
230          }
231
232       // Delete any items which are currently in the FastList but
233       // which aren't in our AsidList.
234       //
235       HLISTITEM hItemNext;
236       for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = hItemNext)
237          {
238          hItemNext = FastList_FindNext (hList, hItem);
239          ASID idObject = (ASID)FastList_GetItemParam (hList, hItem);
240          if (!pAsidList->fIsInList ((PVOID)idObject))
241             FastList_RemoveItem (hList, hItem);
242          }
243
244       // Add items for any entries which are in our AsidList but aren't
245       // currently in the FastList.
246       //
247       DWORD dwStyle = GetWindowLong (hList, GWL_STYLE);
248
249       for (LPENUM pEnum = pAsidList->FindFirst(); pEnum; pEnum = pEnum->FindNext())
250          {
251          ASID idObject = (ASID)( pEnum->GetObject() );
252
253          HLISTITEM hItem;
254          if ((hItem = FastList_FindItem (hList, (LPARAM)idObject)) == NULL)
255             {
256             FASTLISTADDITEM ai;
257             memset (&ai, 0x00, sizeof(ai));
258             Display_GetImageIcons (dwStyle, gr.ivGrp, idObject, imageGROUP, IMAGE_NOIMAGE, &ai.iFirstImage, &ai.iSecondImage);
259             ai.lParam = (LPARAM)idObject;
260             hItem = FastList_AddItem (hList, &ai);
261             }
262          }
263
264       Delete (pAsidList);
265       FastList_End (hList);
266       }
267
268    Display_StopWorking();
269 }
270
271
272 void Display_OnEndTask_UpdMachines (LPTASKPACKET ptp)
273 {
274    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
275    HWND hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
276    if (IsWindow (hList) && !lstrcmpi (TASKDATA(ptp)->szPattern, g.szPatternMachines))
277       {
278       FastList_Begin (hList);
279
280       // Update the title above the list to indicate what we're showing
281       //
282       TCHAR szCell[ cchRESOURCE ];
283       asc_CellNameGet_Fast (g.idClient, g.idCell, szCell);
284
285       LPTSTR pszTitle = FormatString ((TASKDATA(ptp)->szPattern[0]) ? IDS_MACHINES_PATTERN : IDS_MACHINES_ALL, TEXT("%s"), szCell);
286       SetDlgItemText (hDlg, IDC_MACHINES_TITLE, pszTitle);
287       FreeString (pszTitle);
288
289       // For faster access, we'll want to use a hashlist to deal with
290       // the items in our ASIDLIST (right now it's just a flat array).
291       // This lets us remove duplicates--which is no big deal because
292       // there shouldn't be any anyway--but more importantly it lets
293       // us instantly determine if a particular ASID is in the list
294       // (the asc_AsidListTest function is O(n), and we need O(1)).
295       //
296       LPHASHLIST pAsidList = New (HASHLIST);
297       if (TASKDATA(ptp)->pAsidList)
298          {
299          for (size_t iAsid = 0; iAsid < TASKDATA(ptp)->pAsidList->cEntries; ++iAsid)
300             pAsidList->AddUnique ((PVOID)(TASKDATA(ptp)->pAsidList->aEntries[ iAsid ].idObject));
301          }
302
303       // Delete any items which are currently in the FastList but
304       // which aren't in our AsidList.
305       //
306       HLISTITEM hItemNext;
307       for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = hItemNext)
308          {
309          hItemNext = FastList_FindNext (hList, hItem);
310          ASID idObject = (ASID)FastList_GetItemParam (hList, hItem);
311          if (!pAsidList->fIsInList ((PVOID)idObject))
312             FastList_RemoveItem (hList, hItem);
313          }
314
315       // Add items for any entries which are in our AsidList but aren't
316       // currently in the FastList.
317       //
318       DWORD dwStyle = GetWindowLong (hList, GWL_STYLE);
319
320       for (LPENUM pEnum = pAsidList->FindFirst(); pEnum; pEnum = pEnum->FindNext())
321          {
322          ASID idObject = (ASID)( pEnum->GetObject() );
323
324          HLISTITEM hItem;
325          if ((hItem = FastList_FindItem (hList, (LPARAM)idObject)) == NULL)
326             {
327             FASTLISTADDITEM ai;
328             memset (&ai, 0x00, sizeof(ai));
329             Display_GetImageIcons (dwStyle, gr.ivMch, idObject, imageSERVER, IMAGE_NOIMAGE, &ai.iFirstImage, &ai.iSecondImage);
330             ai.lParam = (LPARAM)idObject;
331             hItem = FastList_AddItem (hList, &ai);
332             }
333          }
334
335       Delete (pAsidList);
336       FastList_End (hList);
337       }
338
339    Display_StopWorking();
340 }
341
342
343 void Display_RefreshView (LPVIEWINFO pviNew, ICONVIEW ivNew)
344 {
345    // Find the current VIEWINFO and ICONVIEW settings
346    //
347    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
348
349    HWND hList;
350    LPVIEWINFO pviOld;
351    ICONVIEW *pivOld;
352    switch (Display_GetActiveTab())
353       {
354       case ttUSERS:
355          pivOld = &gr.ivUsr;
356          pviOld = &gr.viewUsr;
357          hList = GetDlgItem (hDlg, IDC_USERS_LIST);
358          break;
359
360       case ttGROUPS:
361          pivOld = &gr.ivGrp;
362          pviOld = &gr.viewGrp;
363          hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
364          break;
365
366       case ttMACHINES:
367          pivOld = &gr.ivMch;
368          pviOld = &gr.viewMch;
369          hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
370          break;
371       }
372
373    if (IsWindow(hList))
374       {
375       FastList_Begin (hList);
376
377       // If the VIEWINFO state has changed, fix it. This will change between
378       // large icons, small icons and details, as well as correct the currently-
379       // displayed columns to match what's in the new VIEWINFO structure.
380       //
381       BOOL fChangedLayouts = FALSE;
382
383       if (memcmp (pviOld, pviNew, sizeof(VIEWINFO)))
384          {
385          FL_RestoreView (hList, pviNew);
386          fChangedLayouts = ((pviOld->lvsView & FLS_VIEW_MASK) != (pviNew->lvsView & FLS_VIEW_MASK)) ? TRUE : FALSE;
387          memcpy (pviOld, pviNew, sizeof(VIEWINFO));
388          }
389
390       // If the ICONVIEW state has changed, fix all items to show just
391       // the appropriate icons. We'll also have to do this if we just changed
392       // from details/small/large icons to another layout (that's what
393       // fChangedLayouts indicates)
394       //
395       if ((*pivOld != ivNew) || (fChangedLayouts))
396          {
397          DWORD dwStyle = GetWindowLong (hList, GWL_STYLE);
398
399          HLISTITEM hItem = NULL;
400          while ((hItem = FastList_FindNext (hList, hItem)) != NULL)
401             {
402             ASID idObject = (ASID)FastList_GetItemParam (hList, hItem);
403
404             int iFirstImage;
405             int iSecondImage;
406             if (pviOld == &gr.viewUsr)
407                Display_GetImageIcons (dwStyle, ivNew, idObject, imageUSER, IMAGE_NOIMAGE, &iFirstImage, &iSecondImage);
408             else if (pviOld == &gr.viewGrp)
409                Display_GetImageIcons (dwStyle, ivNew, idObject, imageGROUP, IMAGE_NOIMAGE, &iFirstImage, &iSecondImage);
410             else
411                Display_GetImageIcons (dwStyle, ivNew, idObject, imageSERVER, IMAGE_NOIMAGE, &iFirstImage, &iSecondImage);
412
413             FastList_SetItemFirstImage (hList, hItem, iFirstImage);
414             FastList_SetItemSecondImage (hList, hItem, iSecondImage);
415             }
416
417          *pivOld = ivNew;
418          }
419
420       FastList_End (hList);
421       }
422 }
423
424
425 void Display_RefreshView_Fast (void)
426 {
427    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
428    HWND hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
429    if (!IsWindow (hList))
430       hList = GetDlgItem (hDlg, IDC_USERS_LIST);
431    if (!IsWindow (hList))
432       hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
433    if (IsWindow (hList))
434       {
435       RECT rWindow;
436       GetClientRect (hList, &rWindow);
437       InvalidateRect (hList, &rWindow, FALSE);
438       UpdateWindow (hList);
439       }
440 }
441
442
443 void Display_SelectAll (void)
444 {
445    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
446    HWND hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
447    if (!IsWindow (hList))
448       hList = GetDlgItem (hDlg, IDC_USERS_LIST);
449    if (!IsWindow (hList))
450       hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
451    if (IsWindow (hList))
452       {
453       // Select all items in the list
454       //
455       FastList_SelectAll (hList);
456
457       // Simulate a FLN_ITEMSELECT notification (since we changed
458       // the selection programmatically, no notification will have been
459       // sent).
460       //
461       FLN_ITEMSELECT_PARAMS fln;
462       fln.hdr.hwndFrom = hList;
463       fln.hdr.idFrom = GetWindowLong (hList, GWL_ID);
464       fln.hdr.code = FLN_ITEMSELECT;
465       fln.hItem = FastList_FindFirstSelected (hList);
466       SendMessage (GetParent (hList), WM_NOTIFY, (WPARAM)fln.hdr.idFrom, (LPARAM)&fln);
467       }
468 }
469
470
471 LPASIDLIST Display_GetSelectedList (void)
472 {
473    LPASIDLIST pAsidList = NULL;
474
475    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
476    HWND hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
477    if (!IsWindow (hList))
478       hList = GetDlgItem (hDlg, IDC_USERS_LIST);
479    if (!IsWindow (hList))
480       hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
481    if (IsWindow (hList))
482       {
483       if (asc_AsidListCreate (&pAsidList))
484          {
485          for (HLISTITEM hItem = FastList_FindFirstSelected (hList);
486               hItem != NULL;
487               hItem = FastList_FindNextSelected (hList, hItem))
488             {
489             ASID idObject = (ASID)FastList_GetItemParam (hList, hItem);
490             if (idObject)
491                asc_AsidListAddEntry (&pAsidList, idObject, 0);
492             }
493          }
494       }
495
496    return pAsidList;
497 }
498
499
500 size_t Display_GetSelectedCount (void)
501 {
502    size_t cSelected = 0;
503
504    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
505    HWND hList = GetDlgItem (hDlg, IDC_GROUPS_LIST);
506    if (!IsWindow (hList))
507       hList = GetDlgItem (hDlg, IDC_USERS_LIST);
508    if (!IsWindow (hList))
509       hList = GetDlgItem (hDlg, IDC_MACHINES_LIST);
510    if (IsWindow (hList))
511       {
512       for (HLISTITEM hItem = FastList_FindFirstSelected (hList);
513            hItem != NULL;
514            hItem = FastList_FindNextSelected (hList, hItem))
515          {
516          ++cSelected;
517          }
518       }
519
520    return cSelected;
521 }
522
523
524 TABTYPE Display_GetActiveTab (void)
525 {
526    HWND hDlg = GetTabChild (GetDlgItem (g.hMain, IDC_TAB));
527    if (IsWindow (GetDlgItem (hDlg, IDC_GROUPS_LIST)))
528       return ttGROUPS;
529    if (IsWindow (GetDlgItem (hDlg, IDC_MACHINES_LIST)))
530       return ttMACHINES;
531    return ttUSERS;
532 }
533
534
535 /*
536  * ROUTINES ___________________________________________________________________
537  *
538  */
539
540 BOOL Display_HandleColumnNotify (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp, LPVIEWINFO pvi)
541 {
542    if (msg == WM_NOTIFY)
543       {
544       HWND hList = GetDlgItem (hDlg, (int)((LPNMHDR)lp)->idFrom);
545       if (fIsFastList (hList))
546          {
547          switch (((LPNMHDR)lp)->code)
548             { 
549             case FLN_COLUMNRESIZE:
550                FL_StoreView (hList, pvi);
551                return TRUE;
552
553             case FLN_COLUMNCLICK:
554                LPFLN_COLUMNCLICK_PARAMS pp = (LPFLN_COLUMNCLICK_PARAMS)lp;
555
556                int iCol;
557                BOOL fRev;
558                FastList_GetSortStyle (hList, &iCol, &fRev);
559
560                if (iCol == pp->icol)
561                   FastList_SetSortStyle (hList, iCol, !fRev);
562                else
563                   FastList_SetSortStyle (hList, pp->icol, FALSE);
564
565                FL_StoreView (hList, pvi);
566                return TRUE;
567             }
568          }
569       }
570
571    return FALSE;
572 }
573
574
575 BOOL CALLBACK Display_GetItemText (HWND hList, LPFLN_GETITEMTEXT_PARAMS pfln, UINT_PTR dwCookie)
576
577    LPVIEWINFO lpvi = (LPVIEWINFO)dwCookie;
578    ASID idObject = (ASID)(pfln->item.lParam);
579
580    pfln->item.pszText[0] = TEXT('\0');
581
582    if ((idObject) && (pfln->item.icol < (int)lpvi->nColsShown))
583       {
584       size_t iCol = lpvi->aColumns[ pfln->item.icol ];
585
586       if (lpvi == &gr.viewUsr)
587          {
588          User_GetColumn (idObject, (USERCOLUMN)iCol, pfln->item.pszText, NULL, NULL, NULL);
589          }
590       else if (lpvi == &gr.viewGrp)
591          {
592          Group_GetColumn (idObject, (GROUPCOLUMN)iCol, pfln->item.pszText, NULL, NULL, NULL);
593          }
594       else if (lpvi == &gr.viewMch)
595          {
596          Machine_GetColumn (idObject, (MACHINECOLUMN)iCol, pfln->item.pszText, NULL, NULL, NULL);
597          }
598       }
599
600    return TRUE;
601 }
602
603
604 void Display_GetImageIcons (DWORD dwStyle, ICONVIEW iv, ASID idObject, int iImageNormal, int iImageAlert, int *piFirstImage, int *piSecondImage)
605 {
606    BOOL fAlert = FALSE;
607
608    if ((dwStyle & FLS_VIEW_MASK) != FLS_VIEW_LIST)
609       iv = ivONEICON;
610
611    switch (iv)
612       {
613       case ivTWOICONS:
614          *piFirstImage = iImageNormal;
615          *piSecondImage = (fAlert) ? iImageAlert : IMAGE_BLANKIMAGE;
616          break;
617
618       case ivONEICON:
619          *piFirstImage = (fAlert) ? iImageAlert : iImageNormal;
620          *piSecondImage = IMAGE_NOIMAGE;
621          break;
622
623       case ivSTATUS:
624          *piFirstImage = (fAlert) ? iImageAlert : IMAGE_BLANKIMAGE;
625          *piSecondImage = IMAGE_NOIMAGE;
626          break;
627       }
628 }
629