NetIDMgr updates
[krb5.git] / src / windows / identity / ui / newcredwnd.c
1 /*\r
2  * Copyright (c) 2005 Massachusetts Institute of Technology\r
3  *\r
4  * Permission is hereby granted, free of charge, to any person\r
5  * obtaining a copy of this software and associated documentation\r
6  * files (the "Software"), to deal in the Software without\r
7  * restriction, including without limitation the rights to use, copy,\r
8  * modify, merge, publish, distribute, sublicense, and/or sell copies\r
9  * of the Software, and to permit persons to whom the Software is\r
10  * furnished to do so, subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be\r
13  * included in all copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
22  * SOFTWARE.\r
23  */\r
24 \r
25 /* $Id$ */\r
26 \r
27 #include<khmapp.h>\r
28 #include<assert.h>\r
29 \r
30 ATOM khui_newcredwnd_cls;\r
31 \r
32 /* forward dcl */\r
33 static void\r
34 nc_position_credtext(khui_nc_wnd_data * d);\r
35 \r
36 /* Common dialog procedure.  Be careful.  This is used by more than\r
37    one dialog. */\r
38 static INT_PTR CALLBACK \r
39 nc_common_dlg_proc(HWND hwnd,\r
40                    UINT uMsg,\r
41                    WPARAM wParam,\r
42                    LPARAM lParam)\r
43 {\r
44     switch(uMsg) {\r
45     case WM_INITDIALOG:\r
46         {\r
47             khui_nc_wnd_data * d;\r
48 \r
49             d = (khui_nc_wnd_data *) lParam;\r
50 \r
51 #pragma warning(push)\r
52 #pragma warning(disable: 4244)\r
53             SetWindowLongPtr(hwnd, DWLP_USER, lParam);\r
54 #pragma warning(pop)\r
55             if (d->nc->subtype == KMSG_CRED_PASSWORD) {\r
56                 ShowWindow(GetDlgItem(hwnd, IDC_NC_OPTIONS),\r
57                            SW_HIDE);\r
58             }\r
59         }\r
60         return TRUE;\r
61 \r
62     case WM_COMMAND:\r
63         {\r
64             int ctrl_id;\r
65 \r
66             ctrl_id = LOWORD(wParam);\r
67             if (ctrl_id < KHUI_CW_ID_MIN ||\r
68                 ctrl_id > KHUI_CW_ID_MAX) {\r
69                 /* pump it to the parent */\r
70                 PostMessage(GetParent(hwnd), WM_COMMAND, wParam, lParam);\r
71                 return TRUE;\r
72             } /* else we allow the message to fall through and get\r
73                  passed into the identity provider's message\r
74                  handler. */\r
75         }\r
76         break;\r
77 \r
78 #if 0\r
79         /* someday this will be used to draw custom tab buttons.  But\r
80            that's not today */\r
81     case WM_DRAWITEM:\r
82         {\r
83             khui_nc_wnd_data * d;\r
84             int id;\r
85             LPDRAWITEMSTRUCT ds;\r
86 \r
87             d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);\r
88             id = wParam;\r
89             ds = (LPDRAWITEMSTRUCT) lParam;\r
90 \r
91             if(id >= NC_TS_CTRL_ID_MIN && id <= NC_TS_CTRL_ID_MAX) {\r
92                 /*TODO: custom draw the buttons */\r
93             }\r
94             else\r
95                 return FALSE;\r
96         }\r
97         break;\r
98 #endif\r
99 \r
100     case KHUI_WM_NC_NOTIFY:\r
101         {\r
102             khui_nc_wnd_data * d;\r
103             d = (khui_nc_wnd_data *)(LONG_PTR) \r
104                 GetWindowLongPtr(hwnd, DWLP_USER);\r
105 \r
106             /* message sent by parent to notify us of something */\r
107             switch(HIWORD(wParam)) {\r
108             case WMNC_DIALOG_EXPAND:\r
109                 if(hwnd == d->dlg_main) {\r
110                     HWND hw;\r
111                         \r
112                     if(hw = GetDlgItem(hwnd, IDOK))\r
113                         ShowWindow(hw, SW_HIDE);\r
114                     if(hw = GetDlgItem(hwnd, IDCANCEL))\r
115                         ShowWindow(hw, SW_HIDE);\r
116                     if(hw = GetDlgItem(hwnd, IDC_NC_OPTIONS))\r
117                         ShowWindow(hw, SW_HIDE);\r
118 \r
119                     d->r_credtext.bottom = d->r_area.bottom;\r
120 \r
121                     nc_position_credtext(d);\r
122 \r
123                     return TRUE;\r
124                 }\r
125             }\r
126         }\r
127         return TRUE;\r
128     }\r
129 \r
130     /* check if we have a wnd_data, and if so pass the message on to\r
131        the identity provider callback. */\r
132     {\r
133         khui_nc_wnd_data * d;\r
134 \r
135         d = (khui_nc_wnd_data *) (LONG_PTR)\r
136             GetWindowLongPtr(hwnd, DWLP_USER);\r
137 \r
138         if (d && d->nc && d->nc->ident_cb) {\r
139             return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG, hwnd, uMsg, \r
140                                    wParam, lParam);\r
141         }\r
142     }\r
143 \r
144     return FALSE;\r
145 }\r
146 \r
147 static void\r
148 nc_position_credtext(khui_nc_wnd_data * d)\r
149 {\r
150     HWND hw;\r
151 \r
152     hw = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT);\r
153 #ifdef DEBUG\r
154     assert(hw);\r
155 #endif\r
156 \r
157     if (d->r_credtext.bottom < d->r_credtext.top + d->r_row.bottom * 2) {\r
158         /* not enough room */\r
159         if (d->nc->mode == KHUI_NC_MODE_MINI &&\r
160             d->nc->subtype != KMSG_CRED_PASSWORD) {\r
161             PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,\r
162                         MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);\r
163             return;\r
164         } else {\r
165             ShowWindow(hw, SW_HIDE);\r
166             return;\r
167         }\r
168     } else {\r
169         ShowWindow(hw, SW_SHOW);\r
170     }\r
171 \r
172     SetWindowPos(hw, NULL,\r
173                  d->r_credtext.left + d->r_n_input.left, /* x */\r
174                  d->r_credtext.top, /* y */\r
175                  d->r_n_input.right - d->r_n_input.left, /* width */\r
176                  d->r_credtext.bottom - d->r_credtext.top, /* height */\r
177                  SWP_NOACTIVATE | SWP_NOOWNERZORDER | \r
178                  SWP_NOZORDER);\r
179 \r
180     hw = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT_LABEL);\r
181 \r
182     SetWindowPos(hw, NULL,\r
183                  d->r_credtext.left + d->r_n_label.left, /* x */\r
184                  d->r_credtext.top, /* y */\r
185                  d->r_n_label.right - d->r_n_label.left, /* width */\r
186                  d->r_n_label.bottom - d->r_n_label.top, /* height */\r
187                  SWP_NOACTIVATE | SWP_NOOWNERZORDER |\r
188                  SWP_NOZORDER);\r
189 }\r
190 \r
191 /* sorts tab buttons */\r
192 static int __cdecl \r
193 nc_tab_sort_func(const void * v1, const void * v2)\r
194 {\r
195     /* v1 and v2 and of type : khui_new_creds_by_type ** */\r
196     khui_new_creds_by_type *t1, *t2;\r
197 \r
198     t1 = *((khui_new_creds_by_type **) v1);\r
199     t2 = *((khui_new_creds_by_type **) v2);\r
200 \r
201     if(t1->ordinal > 0) {\r
202         if(t2->ordinal > 0) {\r
203             if(t1->ordinal == t2->ordinal)\r
204                 return wcscmp(t1->name, t2->name);\r
205             else\r
206                 /* safe to convert to an int here */\r
207                 return (int) (t1->ordinal - t2->ordinal);\r
208         } else\r
209             return -1;\r
210     } else {\r
211         if(t2->ordinal > 0)\r
212             return 1;\r
213         else if (t1->name && t2->name)\r
214             return wcscmp(t1->name, t2->name);\r
215         else\r
216             return 0;\r
217     }\r
218 }\r
219 \r
220 static void \r
221 nc_notify_types_async(khui_new_creds * c, UINT uMsg,\r
222                       WPARAM wParam, LPARAM lParam)\r
223 {\r
224     khm_size i;\r
225 \r
226     for(i=0; i<c->n_types; i++) {\r
227         PostMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);\r
228     }\r
229 }\r
230 \r
231 static void \r
232 nc_notify_types(khui_new_creds * c, UINT uMsg,\r
233                 WPARAM wParam, LPARAM lParam)\r
234 {\r
235     khm_size i;\r
236 \r
237     for(i=0; i<c->n_types; i++) {\r
238         SendMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);\r
239     }\r
240 }\r
241 \r
242 #define NC_MAXCCH_CREDTEXT 16384\r
243 #define NC_MAXCB_CREDTEXT (NC_MAXCCH_CREDTEXT * sizeof(wchar_t))\r
244 \r
245 static void \r
246 nc_update_credtext(khui_nc_wnd_data * d) \r
247 {\r
248     wchar_t * ctbuf = NULL;\r
249     wchar_t * buf;\r
250     BOOL okEnable = FALSE;\r
251     BOOL validId = FALSE;\r
252     HWND hw = NULL;\r
253     size_t cch = 0;\r
254 \r
255     ctbuf = PMALLOC(NC_MAXCB_CREDTEXT);\r
256 \r
257     assert(ctbuf != NULL);\r
258 \r
259     LoadString(khm_hInstance, IDS_NC_CREDTEXT_TABS, ctbuf, NC_MAXCCH_CREDTEXT);\r
260     StringCchLength(ctbuf, NC_MAXCCH_CREDTEXT, &cch);\r
261     buf = ctbuf + cch;\r
262     nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY, \r
263                     MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), 0);\r
264 \r
265     /* hopefully all the types have updated their credential texts */\r
266     if(d->nc->n_identities == 1) {\r
267         wchar_t main_fmt[256];\r
268         wchar_t id_fmt[256];\r
269         wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];\r
270         wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];\r
271         khm_size cbbuf;\r
272         khm_int32 flags;\r
273 \r
274 \r
275         LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_ONE, \r
276                    main_fmt, (int) ARRAYLENGTH(main_fmt));\r
277 \r
278         cbbuf = sizeof(id_name);\r
279         kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);\r
280 \r
281         kcdb_identity_get_flags(d->nc->identities[0], &flags);\r
282 \r
283         if (flags & KCDB_IDENT_FLAG_INVALID) {\r
284             LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID, \r
285                        id_fmt, (int) ARRAYLENGTH(id_fmt));\r
286         } else if(flags & KCDB_IDENT_FLAG_VALID) {\r
287             LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID, \r
288                        id_fmt, (int) ARRAYLENGTH(id_fmt));\r
289         } else if(d->nc->subtype == KMSG_CRED_NEW_CREDS) {\r
290             LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_CHECKING, \r
291                        id_fmt, (int) ARRAYLENGTH(id_fmt));\r
292         } else {\r
293             LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED, \r
294                        id_fmt, (int) ARRAYLENGTH(id_fmt));\r
295         }\r
296 \r
297         StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);\r
298 \r
299         StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t), \r
300                        main_fmt, id_string);\r
301 \r
302         if (flags & KCDB_IDENT_FLAG_VALID) {\r
303             if (flags & KCDB_IDENT_FLAG_DEFAULT)\r
304                 LoadString(khm_hInstance, IDS_NC_ID_DEF,\r
305                            id_string, ARRAYLENGTH(id_string));\r
306             else if (d->nc->set_default)\r
307                 LoadString(khm_hInstance, IDS_NC_ID_WDEF,\r
308                            id_string, ARRAYLENGTH(id_string));\r
309             else\r
310                 LoadString(khm_hInstance, IDS_NC_ID_NDEF,\r
311                            id_string, ARRAYLENGTH(id_string));\r
312 \r
313             StringCbCat(buf, NC_MAXCB_CREDTEXT - cch * sizeof(wchar_t),\r
314                         id_string);\r
315         }\r
316 \r
317     } else if(d->nc->n_identities > 1) {\r
318         wchar_t *ids_string;\r
319         khm_size cb_ids_string;\r
320 \r
321         wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];\r
322         wchar_t id_fmt[256];\r
323         wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];\r
324 \r
325         wchar_t main_fmt[256];\r
326         khm_size cbbuf;\r
327 \r
328         LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_MANY, \r
329                    main_fmt, (int) ARRAYLENGTH(main_fmt));\r
330 \r
331         /* we are going to concatenate all the identity names into\r
332            a comma separated string */\r
333 \r
334         /* d->nc->n_identities is at least 2 */\r
335         ids_string = PMALLOC((KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) * \r
336                             (d->nc->n_identities - 1));\r
337         cb_ids_string = \r
338             (KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) * \r
339             (d->nc->n_identities - 1);\r
340 \r
341         assert(ids_string != NULL);\r
342 \r
343         ids_string[0] = 0;\r
344 \r
345         {\r
346             khm_size i;\r
347             khm_int32 flags;\r
348 \r
349             for(i=1; i<d->nc->n_identities; i++) {\r
350                 if(i>1) {\r
351                     StringCbCat(ids_string, cb_ids_string, L",");\r
352                 }\r
353 \r
354                 flags = 0;\r
355 \r
356                 cbbuf = sizeof(id_name);\r
357                 kcdb_identity_get_name(d->nc->identities[i], id_name, &cbbuf);\r
358                 kcdb_identity_get_flags(d->nc->identities[i], &flags);\r
359                 if(flags & KCDB_IDENT_FLAG_INVALID) {\r
360                     LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID, \r
361                                id_fmt, (int) ARRAYLENGTH(id_fmt));\r
362                 } else if(flags & KCDB_IDENT_FLAG_VALID) {\r
363                     LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID, \r
364                                id_fmt, (int) ARRAYLENGTH(id_fmt));\r
365                 } else {\r
366                     LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED, \r
367                                id_fmt, (int) ARRAYLENGTH(id_fmt));\r
368                 }\r
369 \r
370                 StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);\r
371                 StringCbCat(ids_string, cb_ids_string, id_string);\r
372             }\r
373 \r
374             cbbuf = sizeof(id_name);\r
375             kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);\r
376             kcdb_identity_get_flags(d->nc->identities[0], &flags);\r
377             if(flags & KCDB_IDENT_FLAG_INVALID) {\r
378                 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID, \r
379                            id_fmt, (int) ARRAYLENGTH(id_fmt));\r
380             } else if(flags & KCDB_IDENT_FLAG_VALID) {\r
381                 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID, \r
382                            id_fmt, (int) ARRAYLENGTH(id_fmt));\r
383             } else {\r
384                 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED, \r
385                            id_fmt, (int) ARRAYLENGTH(id_fmt));\r
386             }\r
387             StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);\r
388 \r
389             StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t), \r
390                            main_fmt, id_string, ids_string);\r
391 \r
392             PFREE(ids_string);\r
393         }\r
394     } else {\r
395         LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_NONE, \r
396                    buf, (int)(NC_MAXCCH_CREDTEXT - cch));\r
397     }\r
398 \r
399     /* now, append the credtext string from each of the cred types */\r
400     {\r
401         khm_size i;\r
402         size_t cb;\r
403         wchar_t * buf;\r
404 \r
405         cb = NC_MAXCB_CREDTEXT;\r
406         buf = ctbuf;\r
407 \r
408         for(i=0; i<d->nc->n_types; i++) {\r
409             if(d->nc->types[i]->credtext != NULL) {\r
410                 StringCbCatEx(buf, cb, \r
411                               d->nc->types[i]->credtext,\r
412                               &buf, &cb,\r
413                               0);\r
414             }\r
415         }\r
416     }\r
417 \r
418     SetDlgItemText(d->dlg_main, IDC_NC_CREDTEXT, ctbuf);\r
419 \r
420     PFREE(ctbuf);\r
421 \r
422     /* so depending on whether the primary identity was found to be\r
423        invalid, we need to disable the Ok button and set the title to\r
424        reflect this */\r
425 \r
426     if(d->nc->n_identities > 0) {\r
427         khm_int32 flags = 0;\r
428 \r
429         if(KHM_SUCCEEDED(kcdb_identity_get_flags(d->nc->identities[0], \r
430                                                &flags)) &&\r
431            (flags & KCDB_IDENT_FLAG_VALID)) {\r
432             validId = TRUE;\r
433         }\r
434     }\r
435 \r
436     if (d->nc->window_title == NULL) {\r
437         if(validId) {\r
438             wchar_t wpostfix[256];\r
439             wchar_t wtitle[KCDB_IDENT_MAXCCH_NAME + 256];\r
440             khm_size cbsize;\r
441 \r
442             cbsize = sizeof(wtitle);\r
443             kcdb_identity_get_name(d->nc->identities[0], wtitle, &cbsize);\r
444 \r
445             if (d->nc->subtype == KMSG_CRED_PASSWORD)\r
446                 LoadString(khm_hInstance, IDS_WTPOST_PASSWORD,\r
447                            wpostfix, (int) ARRAYLENGTH(wpostfix));\r
448             else\r
449                 LoadString(khm_hInstance, IDS_WTPOST_NEW_CREDS, \r
450                            wpostfix, (int) ARRAYLENGTH(wpostfix));\r
451 \r
452             StringCbCat(wtitle, sizeof(wtitle), wpostfix);\r
453 \r
454             SetWindowText(d->nc->hwnd, wtitle);\r
455         } else {\r
456             wchar_t wtitle[256];\r
457 \r
458             if (d->nc->subtype == KMSG_CRED_PASSWORD)\r
459                 LoadString(khm_hInstance, IDS_WT_PASSWORD,\r
460                            wtitle, (int) ARRAYLENGTH(wtitle));\r
461             else\r
462                 LoadString(khm_hInstance, IDS_WT_NEW_CREDS, \r
463                            wtitle, (int) ARRAYLENGTH(wtitle));\r
464 \r
465             SetWindowText(d->nc->hwnd, wtitle);\r
466         }\r
467     }\r
468 \r
469     if(validId || d->nc->subtype == KMSG_CRED_PASSWORD) {\r
470         /* TODO: check if all the required fields have valid values\r
471            before enabling the Ok button */\r
472         okEnable = TRUE;\r
473     }\r
474 \r
475     hw = GetDlgItem(d->dlg_main, IDOK);\r
476     EnableWindow(hw, okEnable);\r
477     hw = GetDlgItem(d->dlg_bb, IDOK);\r
478     EnableWindow(hw, okEnable);\r
479 }\r
480 \r
481 #define CW_PARAM DWLP_USER\r
482 \r
483 static void\r
484 nc_add_control_row(khui_nc_wnd_data * d, \r
485                    HWND label,\r
486                    HWND input,\r
487                    khui_control_size size);\r
488 \r
489 static LRESULT \r
490 nc_handle_wm_create(HWND hwnd,\r
491                     UINT uMsg,\r
492                     WPARAM wParam,\r
493                     LPARAM lParam)\r
494 {\r
495     LPCREATESTRUCT lpc;\r
496     khui_new_creds * c;\r
497     khui_nc_wnd_data * ncd;\r
498     int x, y;\r
499     int width, height;\r
500     RECT r;\r
501 \r
502     lpc = (LPCREATESTRUCT) lParam;\r
503 \r
504     ncd = PMALLOC(sizeof(*ncd));\r
505     ZeroMemory(ncd, sizeof(*ncd));\r
506 \r
507     c = (khui_new_creds *) lpc->lpCreateParams;\r
508     ncd->nc = c;\r
509     c->hwnd = hwnd;\r
510 \r
511 #pragma warning(push)\r
512 #pragma warning(disable: 4244)\r
513     SetWindowLongPtr(hwnd, CW_PARAM, (LONG_PTR) ncd);\r
514 #pragma warning(pop)\r
515 \r
516     /* first try to create the main dialog panel */\r
517     \r
518     assert(c->subtype == KMSG_CRED_NEW_CREDS ||\r
519            c->subtype == KMSG_CRED_PASSWORD);\r
520 \r
521     ncd->dlg_main = CreateDialogParam(khm_hInstance,\r
522                                       MAKEINTRESOURCE(IDD_NC_PASSWORD),\r
523                                       hwnd,\r
524                                       nc_common_dlg_proc,\r
525                                       (LPARAM) ncd);\r
526 #ifdef DEBUG\r
527     assert(ncd->dlg_main);\r
528 #endif\r
529 \r
530     {\r
531         RECT r_main;\r
532         RECT r_area;\r
533         RECT r_row;\r
534         HWND hw;\r
535             \r
536         /* pick out metrics for use by the custom prompter stuff */\r
537         GetWindowRect(ncd->dlg_main, &r_main);\r
538 \r
539         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_PANEL);\r
540 #ifdef DEBUG\r
541         assert(hw);\r
542 #endif\r
543         GetWindowRect(hw, &r_area);\r
544         OffsetRect(&r_area,-r_main.left, -r_main.top);\r
545         CopyRect(&ncd->r_area, &r_area);\r
546 \r
547         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW);\r
548 #ifdef DEBUG\r
549         assert(hw);\r
550 #endif\r
551         GetWindowRect(hw, &r);\r
552         CopyRect(&r_row, &r);\r
553         OffsetRect(&r,-r.left, -r.top);\r
554         CopyRect(&ncd->r_row, &r);\r
555 \r
556         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL);\r
557 #ifdef DEBUG\r
558         assert(hw);\r
559 #endif\r
560         GetWindowRect(hw, &r);\r
561         OffsetRect(&r,-r_row.left, -r_row.top);\r
562         CopyRect(&ncd->r_n_label, &r);\r
563 \r
564         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT);\r
565 #ifdef DEBUG\r
566         assert(hw);\r
567 #endif\r
568         GetWindowRect(hw, &r);\r
569         OffsetRect(&r, -r_row.left, -r_row.top);\r
570         CopyRect(&ncd->r_n_input, &r);\r
571 \r
572         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW_LG);\r
573 #ifdef DEBUG\r
574         assert(hw);\r
575 #endif\r
576         GetWindowRect(hw, &r_row);\r
577 \r
578         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL_LG);\r
579 #ifdef DEBUG\r
580         assert(hw);\r
581 #endif\r
582         GetWindowRect(hw, &r);\r
583         OffsetRect(&r, -r_row.left, -r_row.top);\r
584         CopyRect(&ncd->r_e_label, &r);\r
585 \r
586         hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT_LG);\r
587 #ifdef DEBUG\r
588         assert(hw);\r
589 #endif\r
590         GetWindowRect(hw, &r);\r
591         OffsetRect(&r, -r_row.left, -r_row.top);\r
592         CopyRect(&ncd->r_e_input, &r);\r
593 \r
594         CopyRect(&ncd->r_credtext, &ncd->r_area);\r
595         CopyRect(&ncd->r_idspec, &ncd->r_area);\r
596 \r
597         ncd->r_idspec.bottom = ncd->r_idspec.top;\r
598 \r
599         hw = GetDlgItem(ncd->dlg_main, IDC_NC_CREDTEXT);\r
600 #ifdef DEBUG\r
601         assert(hw);\r
602 #endif\r
603         GetWindowRect(hw, &r);\r
604         OffsetRect(&r, -r_main.left, -r_main.top);\r
605         ncd->r_credtext.bottom = r.bottom;\r
606     }\r
607 \r
608     /* if the mode is 'mini'*/\r
609     r.left = 0;\r
610     r.top = 0;\r
611     if(c->mode == KHUI_NC_MODE_MINI) {\r
612         r.right = NCDLG_WIDTH;\r
613         r.bottom = NCDLG_HEIGHT;\r
614     } else {\r
615         r.right = NCDLG_WIDTH + NCDLG_BBAR_WIDTH;\r
616         r.bottom = NCDLG_HEIGHT + NCDLG_TAB_HEIGHT;\r
617     }\r
618 \r
619     MapDialogRect(ncd->dlg_main, &r);\r
620 \r
621     ncd->r_main.left = 0;\r
622     ncd->r_main.top = 0;\r
623     ncd->r_main.right = NCDLG_WIDTH;\r
624     ncd->r_main.bottom = NCDLG_HEIGHT;\r
625 \r
626     ncd->r_ts.left = 0;\r
627     ncd->r_ts.top = ncd->r_main.bottom;\r
628     ncd->r_ts.right = ncd->r_main.right;\r
629     ncd->r_ts.bottom = ncd->r_ts.top + NCDLG_TAB_HEIGHT;\r
630 \r
631     ncd->r_bb.left = ncd->r_main.right;\r
632     ncd->r_bb.top = 0;\r
633     ncd->r_bb.right = ncd->r_bb.left + NCDLG_BBAR_WIDTH;\r
634     ncd->r_bb.bottom = ncd->r_ts.bottom;\r
635 \r
636     MapDialogRect(ncd->dlg_main, &(ncd->r_main));\r
637     MapDialogRect(ncd->dlg_main, &(ncd->r_ts));\r
638     MapDialogRect(ncd->dlg_main, &(ncd->r_bb));\r
639 \r
640     /* center the new creds window over the main NetIDMgr window */\r
641     width = r.right - r.left;\r
642     height = r.bottom - r.top;\r
643 \r
644     /* adjust width and height to accomodate NC area */\r
645     {\r
646         RECT wr,cr;\r
647 \r
648         GetWindowRect(hwnd, &wr);\r
649         GetClientRect(hwnd, &cr);\r
650 \r
651         /* the non-client and client areas have already been calculated\r
652            at this point.  We just use the difference to adjust the width\r
653            and height */\r
654         width += (wr.right - wr.left) - (cr.right - cr.left);\r
655         height += (wr.bottom - wr.top) - (cr.bottom - cr.top);\r
656     }\r
657 \r
658     GetWindowRect(lpc->hwndParent, &r);\r
659     x = (r.right + r.left)/2 - width / 2;\r
660     y = (r.top + r.bottom)/2 - height / 2;\r
661 \r
662     MoveWindow(hwnd, x, y, width, height, FALSE);\r
663 \r
664     SetWindowPos(ncd->dlg_main, \r
665                  NULL, \r
666                  ncd->r_main.left, \r
667                  ncd->r_main.top,\r
668                  ncd->r_main.right - ncd->r_main.left,\r
669                  ncd->r_main.bottom - ncd->r_main.top,\r
670                  SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | \r
671                  SWP_NOREDRAW | SWP_NOZORDER);\r
672 \r
673     /* IDD_NC_BBAR is the button bar that sits on the right of the\r
674        dialog when the new creds window is in 'expanded' mode. */\r
675 \r
676     ncd->dlg_bb = CreateDialogParam(khm_hInstance,\r
677                                     MAKEINTRESOURCE(IDD_NC_BBAR),\r
678                                     hwnd,\r
679                                     nc_common_dlg_proc,\r
680                                     (LPARAM) ncd);\r
681 \r
682 #ifdef DEBUG\r
683     assert(ncd->dlg_bb);\r
684 #endif\r
685 \r
686     SetWindowPos(ncd->dlg_bb, \r
687                  NULL, \r
688                  ncd->r_bb.left, \r
689                  ncd->r_bb.top,\r
690                  ncd->r_bb.right - ncd->r_bb.left,\r
691                  ncd->r_bb.bottom - ncd->r_bb.top,\r
692                  SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | \r
693                  SWP_NOREDRAW | SWP_NOZORDER);\r
694 \r
695     /* IDD_NC_TS is the tab strip that sits below the main panel when\r
696        the new creds window is in 'expanded' mode */\r
697 \r
698     ncd->dlg_ts = CreateDialogParam(khm_hInstance,\r
699                                     MAKEINTRESOURCE(IDD_NC_TS),\r
700                                     hwnd,\r
701                                     nc_common_dlg_proc,\r
702                                     (LPARAM) ncd);\r
703 \r
704 #ifdef DEBUG\r
705     assert(ncd->dlg_ts);\r
706 #endif\r
707 \r
708     SetWindowPos(ncd->dlg_ts, \r
709                  NULL, \r
710                  ncd->r_ts.left, \r
711                  ncd->r_ts.top,\r
712                  ncd->r_ts.right - ncd->r_ts.left,\r
713                  ncd->r_ts.bottom - ncd->r_ts.top,\r
714                  SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER | \r
715                  SWP_NOREDRAW | SWP_NOZORDER);\r
716 \r
717     if(c->mode == KHUI_NC_MODE_MINI) {\r
718         /* hide and show stuff */\r
719         ShowWindow(ncd->dlg_main, SW_SHOW);\r
720         ShowWindow(ncd->dlg_bb, SW_HIDE);\r
721         ShowWindow(ncd->dlg_ts, SW_HIDE);\r
722 \r
723         nc_position_credtext(ncd);\r
724 \r
725     } else {\r
726         /* hide and show stuff */\r
727         ShowWindow(ncd->dlg_main, SW_SHOW);\r
728         ShowWindow(ncd->dlg_bb, SW_SHOW);\r
729         ShowWindow(ncd->dlg_ts, SW_SHOW);\r
730 \r
731         PostMessage(ncd->dlg_main, KHUI_WM_NC_NOTIFY, \r
732                     MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);\r
733     }\r
734 \r
735     /* Call the identity provider callback to set the identity\r
736        selector controls */\r
737     c->ident_cb(c, WMNC_IDENT_INIT, NULL, 0, 0, (LPARAM) ncd->dlg_main);\r
738 \r
739 #if 0\r
740     {\r
741         HWND hw;\r
742         wchar_t wcaption[64];\r
743 \r
744         LoadString(khm_hInstance, IDS_NC_SETDEF, wcaption,\r
745                    ARRAYLENGTH(wcaption));\r
746 \r
747         /* Now create the set as default button */\r
748         hw = CreateWindow\r
749             (L"BUTTON",\r
750              wcaption,\r
751              WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX,\r
752              0, 0, 100, 100,\r
753              ncd->dlg_main,\r
754              (HMENU) NC_BN_SET_DEF_ID,\r
755              khm_hInstance,\r
756              NULL);\r
757 \r
758         nc_add_control_row(ncd, NULL, hw, KHUI_CTRLSIZE_HALF);\r
759     }\r
760 #endif\r
761     /* we defer the creation of the tab buttons for later */\r
762 \r
763     /* add this to the dialog chain */\r
764     khm_add_dialog(hwnd);\r
765 \r
766     return TRUE;\r
767 }\r
768 \r
769 static void\r
770 nc_add_control_row(khui_nc_wnd_data * d, \r
771                    HWND label,\r
772                    HWND input,\r
773                    khui_control_size size)\r
774 {\r
775     RECT r_row;\r
776     RECT r_label;\r
777     RECT r_input;\r
778     HFONT hf;\r
779 \r
780     hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);\r
781     SendMessage(label, WM_SETFONT, (WPARAM) hf, FALSE);\r
782     SendMessage(input, WM_SETFONT, (WPARAM) hf, FALSE);\r
783 \r
784     CopyRect(&r_row, &d->r_row);\r
785     OffsetRect(&r_row, d->r_idspec.left, d->r_idspec.bottom);\r
786 \r
787     if (size == KHUI_CTRLSIZE_SMALL) {\r
788         CopyRect(&r_label, &d->r_n_label);\r
789         CopyRect(&r_input, &d->r_n_input);\r
790         OffsetRect(&r_label, r_row.left, r_row.top);\r
791         OffsetRect(&r_input, r_row.left, r_row.top);\r
792     } else if (size == KHUI_CTRLSIZE_HALF) {\r
793         CopyRect(&r_label, &d->r_e_label);\r
794         CopyRect(&r_input, &d->r_e_input);\r
795         OffsetRect(&r_label, r_row.left, r_row.top);\r
796         OffsetRect(&r_input, r_row.left, r_row.top);\r
797     } else if (size == KHUI_CTRLSIZE_FULL) {\r
798         CopyRect(&r_label, &d->r_n_label);\r
799         r_label.right = d->r_row.right;\r
800         CopyRect(&r_input, &d->r_n_input);\r
801         OffsetRect(&r_input, r_row.left, r_row.top);\r
802         OffsetRect(&r_input, 0, r_input.bottom);\r
803         r_row.bottom += r_input.bottom;\r
804         OffsetRect(&r_label, r_row.left, r_row.top);\r
805     } else {\r
806         SetRectEmpty(&r_label);\r
807         SetRectEmpty(&r_input);\r
808 #ifdef DEBUG\r
809         assert(FALSE);\r
810 #else\r
811         return;\r
812 #endif\r
813     }\r
814 \r
815     if (label)\r
816         SetWindowPos(label,\r
817                      ((d->hwnd_last_idspec != NULL)?\r
818                       d->hwnd_last_idspec:\r
819                       HWND_TOP),\r
820                      r_label.left, r_label.top,\r
821                      r_label.right - r_label.left,\r
822                      r_label.bottom - r_label.top,\r
823                      SWP_DEFERERASE | SWP_NOACTIVATE |\r
824                      SWP_NOOWNERZORDER);\r
825 \r
826     if (input)\r
827         SetWindowPos(input,\r
828                      (label ? label : ((d->hwnd_last_idspec != NULL)?\r
829                                        d->hwnd_last_idspec:\r
830                                        HWND_TOP)),\r
831                      r_input.left, r_input.top,\r
832                      r_input.right - r_input.left,\r
833                      r_input.bottom - r_input.top,\r
834                      SWP_DEFERERASE | SWP_NOACTIVATE |\r
835                      SWP_NOOWNERZORDER);\r
836 \r
837     d->hwnd_last_idspec = input;\r
838 \r
839     d->r_idspec.bottom = r_row.bottom;\r
840 \r
841     d->r_credtext.top = r_row.bottom;\r
842 \r
843     nc_position_credtext(d);\r
844 }\r
845 \r
846 \r
847 static LRESULT \r
848 nc_handle_wm_destroy(HWND hwnd,\r
849                      UINT uMsg,\r
850                      WPARAM wParam,\r
851                      LPARAM lParam)\r
852 {\r
853     khui_nc_wnd_data * d;\r
854     khm_size i;\r
855 \r
856     /* remove self from dialog chain */\r
857     khm_del_dialog(hwnd);\r
858 \r
859     d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);\r
860 \r
861     d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);\r
862 \r
863     if(d->hwnd_tc_main)\r
864         DestroyWindow(d->hwnd_tc_main);\r
865     for(i=0;i<d->nc->n_types;i++) {\r
866         if(d->nc->types[i]->hwnd_tc) {\r
867             DestroyWindow(d->nc->types[i]->hwnd_tc);\r
868             d->nc->types[i]->hwnd_tc = NULL;\r
869         }\r
870     }\r
871 \r
872     if(d->dlg_bb)\r
873         DestroyWindow(d->dlg_bb);\r
874     if(d->dlg_main)\r
875         DestroyWindow(d->dlg_main);\r
876     if(d->dlg_ts)\r
877         DestroyWindow(d->dlg_ts);\r
878 \r
879     d->dlg_bb = NULL;\r
880     d->dlg_main = NULL;\r
881     d->dlg_ts = NULL;\r
882 \r
883     PFREE(d);\r
884 \r
885     return TRUE;\r
886 }\r
887 \r
888 static LRESULT \r
889 nc_handle_wm_command(HWND hwnd,\r
890                      UINT uMsg,\r
891                      WPARAM wParam,\r
892                      LPARAM lParam)\r
893 {\r
894     khui_nc_wnd_data * d;\r
895     int id;\r
896 \r
897     d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);\r
898 \r
899     switch(HIWORD(wParam)) {\r
900     case BN_CLICKED:\r
901         switch(LOWORD(wParam)) {\r
902 \r
903         case IDOK:\r
904             d->nc->result = KHUI_NC_RESULT_PROCESS;\r
905 \r
906             /* fallthrough */\r
907 \r
908         case IDCANCEL:\r
909             /* the default value for d->nc->result is set to\r
910                KHUI_NC_RESULT_CANCEL */\r
911             d->nc->response = 0;\r
912 \r
913             nc_notify_types(d->nc, \r
914                             KHUI_WM_NC_NOTIFY, \r
915                             MAKEWPARAM(0,WMNC_DIALOG_PREPROCESS), \r
916                             0);\r
917 \r
918             khui_cw_sync_prompt_values(d->nc);\r
919 \r
920             khm_cred_dispatch_process_message(d->nc);\r
921 \r
922             /* we won't know whether to abort or not until we get\r
923                feedback from the plugins, even if the command was\r
924                to cancel */\r
925             {\r
926                 HWND hw;\r
927 \r
928                 hw = GetDlgItem(d->dlg_main, IDOK);\r
929                 EnableWindow(hw, FALSE);\r
930                 hw = GetDlgItem(d->dlg_main, IDCANCEL);\r
931                 EnableWindow(hw, FALSE);\r
932                 hw = GetDlgItem(d->dlg_bb, IDOK);\r
933                 EnableWindow(hw, FALSE);\r
934                 hw = GetDlgItem(d->dlg_bb, IDCANCEL);\r
935                 EnableWindow(hw, FALSE);\r
936             }\r
937             return FALSE;\r
938 \r
939         case IDC_NC_HELP:\r
940             khm_html_help(hwnd, NULL, HH_HELP_CONTEXT, IDH_ACTION_NEW_ID);\r
941             return FALSE;\r
942 \r
943         case IDC_NC_OPTIONS: \r
944             /* the Options button in the main window was clicked.  we\r
945                respond by expanding the dialog. */\r
946             PostMessage(hwnd, KHUI_WM_NC_NOTIFY, \r
947                         MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);\r
948             return FALSE;\r
949 \r
950         case IDC_NC_CREDTEXT: /* credtext link activated */\r
951             {\r
952                 khui_htwnd_link * l;\r
953                 wchar_t sid[KHUI_MAXCCH_HTLINK_FIELD];\r
954                 wchar_t sparam[KHUI_MAXCCH_HTLINK_FIELD];\r
955                 wchar_t * colon;\r
956 \r
957                 l = (khui_htwnd_link *) lParam;\r
958 \r
959                 /* do we have a valid link? */\r
960                 if(l->id == NULL || l->id_len >= ARRAYLENGTH(sid))\r
961                     return TRUE; /* nope */\r
962 \r
963                 StringCchCopyN(sid, ARRAYLENGTH(sid), l->id, l->id_len);\r
964                 sid[l->id_len] = L'\0'; /* just make sure */\r
965 \r
966                 if(l->param != NULL && \r
967                    l->param_len < ARRAYLENGTH(sparam) &&\r
968                    l->param_len > 0) {\r
969 \r
970                     StringCchCopyN(sparam, ARRAYLENGTH(sparam),\r
971                                    l->param, l->param_len);\r
972                     sparam[l->param_len] = L'\0';\r
973 \r
974                 } else {\r
975                     sparam[0] = L'\0';\r
976                 }\r
977 \r
978                 /* If the ID is of the form '<credtype>:<link_tag>'\r
979                    and <credtype> is a valid name of a credentials\r
980                    type that is participating in the credentials\r
981                    acquisition process, then we forward the message to\r
982                    the panel that is providing the UI for that cred\r
983                    type.  We also switch to that panel first. */\r
984 \r
985                 colon = wcschr(sid, L':');\r
986                 if (colon != NULL) {\r
987                     khm_int32 credtype;\r
988                     khui_new_creds_by_type * t;\r
989 \r
990                     *colon = L'\0';\r
991                     if (KHM_SUCCEEDED(kcdb_credtype_get_id(sid, &credtype)) &&\r
992                         KHM_SUCCEEDED(khui_cw_find_type(d->nc, credtype, &t))){\r
993                         *colon = L':';\r
994 \r
995                         if (t->ordinal != d->ctab)\r
996                             PostMessage(hwnd,\r
997                                         KHUI_WM_NC_NOTIFY,\r
998                                         MAKEWPARAM(t->ordinal,\r
999                                                    WMNC_DIALOG_SWITCH_PANEL),\r
1000                                         0);\r
1001 \r
1002                         return SendMessage(t->hwnd_panel,\r
1003                                            KHUI_WM_NC_NOTIFY,\r
1004                                            MAKEWPARAM(0, WMNC_CREDTEXT_LINK),\r
1005                                            lParam);\r
1006                     }\r
1007                 }\r
1008 \r
1009                 /* if it was for us, then we need to process the message */\r
1010                 if(!_wcsicmp(sid, CTLINKID_SWITCH_PANEL)) {\r
1011                     khm_int32 credtype;\r
1012                     khui_new_creds_by_type * t;\r
1013 \r
1014                     if (KHM_SUCCEEDED(kcdb_credtype_get_id(sparam, \r
1015                                                            &credtype)) &&\r
1016                         KHM_SUCCEEDED(khui_cw_find_type(d->nc,\r
1017                                                         credtype, &t))) {\r
1018                         if (t->ordinal != d->ctab)\r
1019                             PostMessage(hwnd,\r
1020                                         KHUI_WM_NC_NOTIFY,\r
1021                                         MAKEWPARAM(t->ordinal,\r
1022                                                    WMNC_DIALOG_SWITCH_PANEL),\r
1023                                         0);\r
1024                     }\r
1025                 } else if (!_wcsicmp(sid, L"NotDef")) {\r
1026                     d->nc->set_default = FALSE;\r
1027                     nc_update_credtext(d);\r
1028                 } else if (!_wcsicmp(sid, L"MakeDef")) {\r
1029                     d->nc->set_default = TRUE;\r
1030                     nc_update_credtext(d);\r
1031                 }\r
1032             }\r
1033             return FALSE;\r
1034 \r
1035 #if 0\r
1036         case NC_BN_SET_DEF_ID:\r
1037             {\r
1038                 d->nc->set_default =\r
1039                     (IsDlgButtonChecked(d->dlg_main, NC_BN_SET_DEF_ID)\r
1040                      == BST_CHECKED);\r
1041             }\r
1042             return FALSE;\r
1043 #endif\r
1044 \r
1045         default:\r
1046             /* if one of the tab strip buttons were pressed, then\r
1047                we should switch to that panel */\r
1048             id = LOWORD(wParam);\r
1049             if(id >= NC_TS_CTRL_ID_MIN && id <= NC_TS_CTRL_ID_MAX) {\r
1050                 id -= NC_TS_CTRL_ID_MIN;\r
1051                 PostMessage(hwnd, KHUI_WM_NC_NOTIFY, \r
1052                             MAKEWPARAM(id, WMNC_DIALOG_SWITCH_PANEL),0);\r
1053                 return FALSE;\r
1054             }\r
1055         }\r
1056         break;\r
1057     }\r
1058 \r
1059     return TRUE;\r
1060 }\r
1061 \r
1062 static LRESULT nc_handle_wm_moving(HWND hwnd,\r
1063                                    UINT uMsg,\r
1064                                    WPARAM wParam,\r
1065                                    LPARAM lParam)\r
1066 {\r
1067     khui_nc_wnd_data * d;\r
1068 \r
1069     d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);\r
1070 \r
1071     nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY, \r
1072                     MAKEWPARAM(0, WMNC_DIALOG_MOVE), 0);\r
1073 \r
1074     return FALSE;\r
1075 }\r
1076 \r
1077 static LRESULT nc_handle_wm_nc_notify(HWND hwnd,\r
1078                                UINT uMsg,\r
1079                                WPARAM wParam,\r
1080                                LPARAM lParam)\r
1081 {\r
1082     khui_nc_wnd_data * d;\r
1083     RECT r;\r
1084     int width, height;\r
1085     khm_size id;\r
1086 \r
1087     d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);\r
1088 \r
1089     switch(HIWORD(wParam)) {\r
1090 \r
1091     case WMNC_DIALOG_SWITCH_PANEL:\r
1092         id = LOWORD(wParam);\r
1093         if(id >= 0 && id <= d->nc->n_types) {\r
1094             /* one of the tab buttons were pressed */\r
1095             if(d->ctab == id) {\r
1096                 return TRUE; /* nothign to do */\r
1097             }\r
1098 \r
1099             if(d->ctab == 0) {\r
1100                 ShowWindow(d->dlg_main, SW_HIDE);\r
1101                 SendMessage(d->hwnd_tc_main, \r
1102                             BM_SETCHECK, BST_UNCHECKED, 0);\r
1103             } else {\r
1104                 ShowWindow(d->nc->types[d->ctab - 1]->hwnd_panel, SW_HIDE);\r
1105                 SendMessage(d->nc->types[d->ctab - 1]->hwnd_tc, \r
1106                             BM_SETCHECK, BST_UNCHECKED, 0);\r
1107             }\r
1108 \r
1109             d->ctab = id;\r
1110 \r
1111             if(d->ctab == 0) {\r
1112                 ShowWindow(d->dlg_main, SW_SHOW);\r
1113                 SendMessage(d->hwnd_tc_main, \r
1114                             BM_SETCHECK, BST_CHECKED, 0);\r
1115             } else {\r
1116                 ShowWindow(d->nc->types[id - 1]->hwnd_panel, SW_SHOW);\r
1117                 SendMessage(d->nc->types[id - 1]->hwnd_tc, \r
1118                             BM_SETCHECK, BST_CHECKED, 0);\r
1119             }\r
1120         }\r
1121 \r
1122         if(d->nc->mode == KHUI_NC_MODE_EXPANDED)\r
1123             return TRUE;\r
1124         /*else*/\r
1125         /* fallthrough */\r
1126 \r
1127     case WMNC_DIALOG_EXPAND:\r
1128         /* we are expanding the dialog box */\r
1129 \r
1130         /* nothing to do? */\r
1131         if (d->nc->mode == KHUI_NC_MODE_EXPANDED)\r
1132             break;\r
1133 \r
1134         d->nc->mode = KHUI_NC_MODE_EXPANDED;\r
1135 \r
1136         r.top = 0;\r
1137         r.left = 0;\r
1138         r.right = NCDLG_WIDTH + NCDLG_BBAR_WIDTH;\r
1139         r.bottom = NCDLG_HEIGHT + NCDLG_TAB_HEIGHT;\r
1140 \r
1141         MapDialogRect(d->dlg_main, &r);\r
1142 \r
1143         width = r.right - r.left;\r
1144         height = r.bottom - r.top;\r
1145 \r
1146         /* adjust width and height to accomodate NC area */\r
1147         {\r
1148             RECT wr,cr;\r
1149 \r
1150             GetWindowRect(hwnd, &wr);\r
1151             GetClientRect(hwnd, &cr);\r
1152 \r
1153             /* the non-client and client areas have already been\r
1154                calculated at this point.  We just use the difference\r
1155                to adjust the width and height */\r
1156             width += (wr.right - wr.left) - (cr.right - cr.left);\r
1157             height += (wr.bottom - wr.top) - (cr.bottom - cr.top);\r
1158         }\r
1159 \r
1160         SendMessage(d->dlg_main, \r
1161                     KHUI_WM_NC_NOTIFY, \r
1162                     MAKEWPARAM(0,WMNC_DIALOG_EXPAND), \r
1163                     0);\r
1164 \r
1165         SetWindowPos(hwnd, \r
1166                      NULL, \r
1167                      0, 0, \r
1168                      width, height, \r
1169                      SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER | \r
1170                      SWP_NOZORDER);\r
1171 \r
1172         ShowWindow(d->dlg_bb, SW_SHOW);\r
1173         ShowWindow(d->dlg_ts, SW_SHOW);\r
1174         break;\r
1175 \r
1176     case WMNC_DIALOG_SETUP:\r
1177         if(d->nc->n_types > 0) {\r
1178             khm_size i;\r
1179             for(i=0; i < d->nc->n_types;i++) {\r
1180 \r
1181                 if (d->nc->types[i]->dlg_proc == NULL) {\r
1182                     d->nc->types[i]->hwnd_panel = NULL;\r
1183                 } else {\r
1184                     /* Create the dialog panel */\r
1185                     d->nc->types[i]->hwnd_panel = \r
1186                         CreateDialogParam(d->nc->types[i]->h_module,\r
1187                                           d->nc->types[i]->dlg_template,\r
1188                                           d->nc->hwnd,\r
1189                                           d->nc->types[i]->dlg_proc,\r
1190                                           (LPARAM) d->nc);\r
1191 \r
1192 #ifdef DEBUG\r
1193                     assert(d->nc->types[i]->hwnd_panel);\r
1194 #endif\r
1195                 }\r
1196             }\r
1197         }\r
1198         break;\r
1199 \r
1200     case WMNC_DIALOG_ACTIVATE:\r
1201         {\r
1202             int x,y,width,height;\r
1203             RECT r;\r
1204             int id;\r
1205             wchar_t wbuf[256];\r
1206             HFONT hf;\r
1207 \r
1208             /* now we create all the tab strip controls */\r
1209             r.left = 0;\r
1210             r.top = 0;\r
1211             r.right = NCDLG_TAB_WIDTH;\r
1212             r.bottom = NCDLG_TAB_HEIGHT;\r
1213             MapDialogRect(d->dlg_main, &r);\r
1214 \r
1215             width = r.right - r.left;\r
1216             height = r.bottom - r.top;\r
1217 \r
1218             x = 0;\r
1219             y = 0;\r
1220 \r
1221             id = NC_TS_CTRL_ID_MIN;\r
1222 \r
1223             khui_cw_lock_nc(d->nc);\r
1224 \r
1225             /* first, the control for the main panel */\r
1226             LoadString(khm_hInstance, IDS_NC_IDENTITY, \r
1227                        wbuf, ARRAYLENGTH(wbuf));\r
1228 \r
1229             d->hwnd_tc_main = \r
1230                 CreateWindow(L"BUTTON",\r
1231                              wbuf,\r
1232                              WS_VISIBLE | WS_CHILD | WS_TABSTOP |\r
1233                              BS_PUSHLIKE | BS_CHECKBOX | BS_TEXT,\r
1234                              x,y,width,height,\r
1235                              d->dlg_ts,\r
1236                              (HMENU)(INT_PTR) id,\r
1237                              khm_hInstance,\r
1238                              NULL);\r
1239 \r
1240             hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);\r
1241             SendMessage(d->hwnd_tc_main, WM_SETFONT, (WPARAM) hf, 0);\r
1242             SendMessage(d->hwnd_tc_main, BM_SETCHECK, BST_CHECKED, 0);\r
1243 \r
1244             id++;\r
1245             x += width;\r
1246 \r
1247             if(d->nc->n_types > 0) {\r
1248                 khm_size i;\r
1249                 /* we should sort the tabs first */\r
1250                 qsort(d->nc->types, \r
1251                       d->nc->n_types, \r
1252                       sizeof(*(d->nc->types)), \r
1253                       nc_tab_sort_func);\r
1254 \r
1255                 for(i=0; i < d->nc->n_types;i++) {\r
1256                     wchar_t * name = NULL;\r
1257 \r
1258                     d->nc->types[i]->ordinal = i + 1;\r
1259 \r
1260                     if(d->nc->types[i]->name)\r
1261                         name = d->nc->types[i]->name;\r
1262                     else {\r
1263                         khm_size cbsize;\r
1264 \r
1265                         if(kcdb_credtype_describe\r
1266                            (d->nc->types[i]->type, \r
1267                             NULL, \r
1268                             &cbsize, \r
1269                             KCDB_TS_SHORT) == KHM_ERROR_TOO_LONG) {\r
1270 \r
1271                             name = PMALLOC(cbsize);\r
1272                             kcdb_credtype_describe(d->nc->types[i]->type, \r
1273                                                    name, \r
1274                                                    &cbsize, \r
1275                                                    KCDB_TS_SHORT);\r
1276                         } else {\r
1277 #ifdef DEBUG\r
1278                             assert(FALSE);\r
1279 #else\r
1280                             continue;\r
1281 #endif\r
1282                         }\r
1283                     }\r
1284 \r
1285                     d->nc->types[i]->hwnd_tc = \r
1286                         CreateWindow(L"BUTTON",\r
1287                                      name,\r
1288                                      WS_VISIBLE | WS_CHILD | WS_TABSTOP |\r
1289                                      BS_PUSHLIKE | BS_CHECKBOX | BS_TEXT |\r
1290                                      ((d->nc->types[i]->hwnd_panel == NULL)? \r
1291                                       WS_DISABLED : 0),\r
1292                                      x,y,width,height,\r
1293                                      d->dlg_ts,\r
1294                                      (HMENU)(INT_PTR) id,\r
1295                                      khm_hInstance,\r
1296                                      NULL);\r
1297 \r
1298                     SendMessage(d->nc->types[i]->hwnd_tc, WM_SETFONT, \r
1299                                 (WPARAM)hf, 0);\r
1300 \r
1301 #if 0\r
1302                     if(d->nc->types[i]->flags & KHUI_NCT_FLAG_DISABLED)\r
1303                         SendMessage(d->nc->types[i]->hwnd_tc, \r
1304                                     BM_SETIMAGE, \r
1305                                     IMAGE_ICON, \r
1306                                     LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_DISABLED)));\r
1307                     else\r
1308                         SendMessage(d->nc->types[i]->hwnd_tc, \r
1309                                     BM_SETIMAGE, \r
1310                                     IMAGE_ICON, \r
1311                                     LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_ENABLED)));\r
1312 #endif\r
1313 \r
1314                     id++;\r
1315                     x += width;\r
1316 \r
1317                     if(!(d->nc->types[i]->name))\r
1318                         PFREE(name);\r
1319 \r
1320                     /* Now set the position of the type panel */\r
1321                     ShowWindow(d->nc->types[i]->hwnd_panel, SW_HIDE);\r
1322                     SetWindowPos(d->nc->types[i]->hwnd_panel, \r
1323                                  NULL,\r
1324                                  d->r_main.left, \r
1325                                  d->r_main.top,\r
1326                                  d->r_main.right - d->r_main.left,\r
1327                                  d->r_main.bottom - d->r_main.top,\r
1328                                  SWP_DEFERERASE | SWP_NOACTIVATE | \r
1329                                  SWP_NOOWNERZORDER | SWP_NOREDRAW | \r
1330                                  SWP_NOZORDER);\r
1331 \r
1332                 }\r
1333             }\r
1334 \r
1335             khui_cw_unlock_nc(d->nc);\r
1336 \r
1337             nc_update_credtext(d);\r
1338 \r
1339             ShowWindow(hwnd, SW_SHOW);\r
1340             SetFocus(hwnd);\r
1341 \r
1342             if (d->nc->n_identities == 0)\r
1343                 break;\r
1344             /* else */\r
1345             /*   fallthrough */\r
1346         }\r
1347 \r
1348     case WMNC_IDENTITY_CHANGE:\r
1349         {\r
1350             BOOL okEnable = FALSE;\r
1351 \r
1352             nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,\r
1353                             MAKEWPARAM(0, WMNC_IDENTITY_CHANGE), 0);\r
1354 \r
1355             if (d->nc->subtype == KMSG_CRED_NEW_CREDS &&\r
1356                 d->nc->n_identities > 0 &&\r
1357                 d->nc->identities[0]) {\r
1358                 khm_int32 f = 0;\r
1359 \r
1360                 kcdb_identity_get_flags(d->nc->identities[0], &f);\r
1361 \r
1362                 if (!(f & KCDB_IDENT_FLAG_DEFAULT)) {\r
1363                     d->nc->set_default = FALSE;\r
1364                 }\r
1365             }\r
1366 \r
1367             nc_update_credtext(d);\r
1368 \r
1369         }\r
1370         break;\r
1371 \r
1372     case WMNC_TYPE_STATE:\r
1373         /* fallthrough */\r
1374     case WMNC_UPDATE_CREDTEXT:\r
1375         nc_update_credtext(d);\r
1376         break;\r
1377 \r
1378     case WMNC_CLEAR_PROMPTS:\r
1379         {\r
1380             khm_size i;\r
1381 \r
1382             khui_cw_lock_nc(d->nc);\r
1383 \r
1384             if(d->hwnd_banner != NULL) {\r
1385                 DestroyWindow(d->hwnd_banner);\r
1386                 d->hwnd_banner = NULL;\r
1387             }\r
1388 \r
1389             if(d->hwnd_name != NULL) {\r
1390                 DestroyWindow(d->hwnd_name);\r
1391                 d->hwnd_name = NULL;\r
1392             }\r
1393 \r
1394             for(i=0;i<d->nc->n_prompts;i++) {\r
1395                 if(!(d->nc->prompts[i]->flags & \r
1396                      KHUI_NCPROMPT_FLAG_STOCK)) {\r
1397                     if(d->nc->prompts[i]->hwnd_static != NULL)\r
1398                         DestroyWindow(d->nc->prompts[i]->hwnd_static);\r
1399 \r
1400                     if(d->nc->prompts[i]->hwnd_edit != NULL)\r
1401                         DestroyWindow(d->nc->prompts[i]->hwnd_edit);\r
1402                 }\r
1403 \r
1404                 d->nc->prompts[i]->hwnd_static = NULL;\r
1405                 d->nc->prompts[i]->hwnd_edit = NULL;\r
1406             }\r
1407 \r
1408             khui_cw_unlock_nc(d->nc);\r
1409 \r
1410             d->r_credtext.top = d->r_idspec.bottom;\r
1411 \r
1412             nc_position_credtext(d);\r
1413         }\r
1414         break;\r
1415 \r
1416     case WMNC_SET_PROMPTS:\r
1417         {\r
1418             khm_size i;\r
1419             int  y;\r
1420             HWND hw, hw_prev;\r
1421             HFONT hf, hfold;\r
1422             HDC hdc;\r
1423 \r
1424             /* we assume that WMNC_CLEAR_PROMPTS has already been\r
1425                received */\r
1426 \r
1427             khui_cw_lock_nc(d->nc);\r
1428 \r
1429 #if 0\r
1430             /* special case, we have one prompt and it is a password\r
1431                prompt.  very common */\r
1432             if(d->nc->n_prompts == 1 && \r
1433                d->nc->prompts[0]->type == KHUI_NCPROMPT_TYPE_PASSWORD) {\r
1434 \r
1435                 hw = GetDlgItem(d->dlg_main, IDC_NC_PASSWORD);\r
1436                 EnableWindow(hw, TRUE);\r
1437 \r
1438                 d->nc->prompts[0]->flags |= KHUI_NCPROMPT_FLAG_STOCK;\r
1439                 d->nc->prompts[0]->hwnd_edit = hw;\r
1440                 d->nc->prompts[0]->hwnd_static = NULL; /* don't care */\r
1441 \r
1442                 khui_cw_unlock_nc(d->nc);\r
1443                 break;\r
1444             }\r
1445 #endif\r
1446             /* for everything else */\r
1447 \r
1448             /* hide the stock password controls */\r
1449 #if 0\r
1450             /* TAGREMOVE */\r
1451             hw = GetDlgItem(d->dlg_main, IDC_NC_PASSWORD);\r
1452             ShowWindow(hw, SW_HIDE);\r
1453             hw = GetDlgItem(d->dlg_main, IDC_NC_PASSWORD_LABEL);\r
1454             ShowWindow(hw, SW_HIDE);\r
1455 #endif\r
1456 \r
1457             y = d->r_idspec.bottom;\r
1458 \r
1459             hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);\r
1460 \r
1461             if (d->nc->pname != NULL) {\r
1462                 hw =\r
1463                     CreateWindowEx\r
1464                     (0,\r
1465                      L"STATIC",\r
1466                      d->nc->pname,\r
1467                      SS_SUNKEN | WS_CHILD,\r
1468                      d->r_area.left, y,\r
1469                      d->r_row.right, \r
1470                      d->r_n_label.bottom - d->r_n_label.top,\r
1471                      d->dlg_main,\r
1472                      NULL,\r
1473                      khm_hInstance,\r
1474                      NULL);\r
1475 \r
1476 #ifdef DEBUG\r
1477                 assert(hw);\r
1478 #endif\r
1479                 d->hwnd_name = hw;\r
1480                 SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM) TRUE);\r
1481                 ShowWindow(hw, SW_SHOW);\r
1482 \r
1483                 y += d->r_n_label.bottom - d->r_n_label.top;\r
1484             }\r
1485 \r
1486             if (d->nc->banner != NULL) {\r
1487                 hw = \r
1488                     CreateWindowEx\r
1489                     (0,\r
1490                      L"STATIC",\r
1491                      d->nc->banner,\r
1492                      WS_CHILD,\r
1493                      d->r_area.left, y,\r
1494                      d->r_row.right, d->r_row.bottom,\r
1495                      d->dlg_main,\r
1496                      NULL,\r
1497                      khm_hInstance,\r
1498                      NULL);\r
1499 #ifdef DEBUG\r
1500                 assert(hw);\r
1501 #endif\r
1502                 d->hwnd_banner = hw;\r
1503                 SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM)TRUE);\r
1504                 ShowWindow(hw, SW_SHOW);\r
1505                 y += d->r_row.bottom;\r
1506             }\r
1507 \r
1508             hw_prev = d->hwnd_last_idspec;\r
1509 \r
1510             hdc = GetWindowDC(d->dlg_main);\r
1511             hfold = SelectObject(hdc,hf);\r
1512 \r
1513             for(i=0; i<d->nc->n_prompts; i++) {\r
1514                 RECT pr, er;\r
1515                 SIZE s;\r
1516                 int dy;\r
1517 \r
1518                 if(d->nc->prompts[i]->prompt != NULL) {\r
1519                     GetTextExtentPoint32(hdc, \r
1520                                          d->nc->prompts[i]->prompt, \r
1521                                          (int) wcslen(d->nc->prompts[i]->prompt),\r
1522                                          &s);\r
1523                     if(s.cx < d->r_n_label.right - d->r_n_label.left) {\r
1524                         CopyRect(&pr, &d->r_n_label);\r
1525                         CopyRect(&er, &d->r_n_input);\r
1526                         dy = d->r_row.bottom;\r
1527                     } else if(s.cx < \r
1528                               d->r_e_label.right - d->r_e_label.left) {\r
1529                         CopyRect(&pr, &d->r_e_label);\r
1530                         CopyRect(&er, &d->r_e_input);\r
1531                         dy = d->r_row.bottom;\r
1532                     } else {\r
1533                         /* oops. the prompt doesn't fit in our\r
1534                            controls.  we need to use up two lines */\r
1535                         pr.left = 0;\r
1536                         pr.right = d->r_row.right;\r
1537                         pr.top = 0;\r
1538                         pr.bottom = d->r_n_label.bottom - \r
1539                             d->r_n_label.top;\r
1540                         CopyRect(&er, &d->r_n_input);\r
1541                         OffsetRect(&er, 0, pr.bottom);\r
1542                         dy = er.bottom + (d->r_row.bottom - \r
1543                                           d->r_n_input.bottom);\r
1544                     }\r
1545                 } else {\r
1546                     SetRectEmpty(&pr);\r
1547                     CopyRect(&er, &d->r_n_input);\r
1548                     dy = d->r_row.bottom;\r
1549                 }\r
1550 \r
1551                 if(IsRectEmpty(&pr)) {\r
1552                     d->nc->prompts[i]->hwnd_static = NULL;\r
1553                 } else {\r
1554                     OffsetRect(&pr, d->r_area.left, y);\r
1555 \r
1556                     hw = CreateWindowEx\r
1557                         (0,\r
1558                          L"STATIC",\r
1559                          d->nc->prompts[i]->prompt,\r
1560                          WS_CHILD,\r
1561                          pr.left, pr.top,\r
1562                          pr.right - pr.left, pr.bottom - pr.top,\r
1563                          d->dlg_main,\r
1564                          NULL,\r
1565                          khm_hInstance,\r
1566                          NULL);\r
1567 #ifdef DEBUG\r
1568                     assert(hw);\r
1569 #endif\r
1570 \r
1571                     SendMessage(hw, WM_SETFONT, \r
1572                                 (WPARAM) hf, (LPARAM) TRUE);\r
1573 \r
1574                     SetWindowPos(hw, hw_prev,\r
1575                                  0, 0, 0, 0,\r
1576                                  SWP_NOACTIVATE | SWP_NOMOVE |\r
1577                                  SWP_NOOWNERZORDER | SWP_NOSIZE |\r
1578                                  SWP_SHOWWINDOW);\r
1579 \r
1580                     d->nc->prompts[i]->hwnd_static = hw;\r
1581                     hw_prev = hw;\r
1582                 }\r
1583 \r
1584                 OffsetRect(&er, d->r_area.left, y);\r
1585 \r
1586                 hw = CreateWindowEx\r
1587                     (0,\r
1588                      L"EDIT",\r
1589                      (d->nc->prompts[i]->def ? \r
1590                       d->nc->prompts[i]->def : L""),\r
1591                      WS_CHILD | WS_TABSTOP |\r
1592                      WS_BORDER |\r
1593                      ((d->nc->prompts[i]->flags & \r
1594                        KHUI_NCPROMPT_FLAG_HIDDEN)? ES_PASSWORD:0),\r
1595                      er.left, er.top,\r
1596                      er.right - er.left, er.bottom - er.top,\r
1597                      d->dlg_main,\r
1598                      NULL,\r
1599                      khm_hInstance,\r
1600                      NULL);\r
1601 \r
1602 #ifdef DEBUG\r
1603                 assert(hw);\r
1604 #endif\r
1605 \r
1606                 SendMessage(hw, WM_SETFONT, \r
1607                             (WPARAM) hf, (LPARAM) TRUE);\r
1608 \r
1609                 SetWindowPos(hw, hw_prev,\r
1610                              0, 0, 0, 0, \r
1611                              SWP_NOACTIVATE | SWP_NOMOVE | \r
1612                              SWP_NOOWNERZORDER | SWP_NOSIZE | \r
1613                              SWP_SHOWWINDOW);\r
1614 \r
1615                 SendMessage(hw, EM_SETLIMITTEXT,\r
1616                             KHUI_MAXCCH_PROMPT_VALUE -1,\r
1617                             0);\r
1618 \r
1619                 d->nc->prompts[i]->hwnd_edit = hw;\r
1620 \r
1621                 hw_prev = hw;\r
1622 \r
1623                 y += dy;\r
1624             }\r
1625 \r
1626             SelectObject(hdc, hfold);\r
1627             ReleaseDC(d->dlg_main, hdc);\r
1628 \r
1629             khui_cw_unlock_nc(d->nc);\r
1630 \r
1631             d->r_credtext.top = y;\r
1632 \r
1633             nc_position_credtext(d);\r
1634         }\r
1635         break;\r
1636 \r
1637     case WMNC_DIALOG_PROCESS_COMPLETE:\r
1638         {\r
1639             khui_new_creds * nc;\r
1640 \r
1641             nc = d->nc;\r
1642 \r
1643             if(nc->response & KHUI_NC_RESPONSE_NOEXIT) {\r
1644                 HWND hw;\r
1645 \r
1646                 /* reset state */\r
1647                 nc->result = KHUI_NC_RESULT_CANCEL;\r
1648 \r
1649                 hw = GetDlgItem(d->dlg_main, IDOK);\r
1650                 EnableWindow(hw, TRUE);\r
1651                 hw = GetDlgItem(d->dlg_main, IDCANCEL);\r
1652                 EnableWindow(hw, TRUE);\r
1653                 hw = GetDlgItem(d->dlg_bb, IDOK);\r
1654                 EnableWindow(hw, TRUE);\r
1655                 hw = GetDlgItem(d->dlg_bb, IDCANCEL);\r
1656                 EnableWindow(hw, TRUE);\r
1657 \r
1658                 return TRUE;\r
1659             }\r
1660 \r
1661             DestroyWindow(hwnd);\r
1662 \r
1663             kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, (void *) nc);\r
1664         }\r
1665         break;\r
1666 \r
1667         /* MUST be called with SendMessage */\r
1668     case WMNC_ADD_CONTROL_ROW:\r
1669         {\r
1670             khui_control_row * row;\r
1671 \r
1672             row = (khui_control_row *) lParam;\r
1673 \r
1674 #ifdef DEBUG\r
1675             assert(row->label);\r
1676             assert(row->input);\r
1677 #endif\r
1678 \r
1679             nc_add_control_row(d, row->label, row->input, row->size);\r
1680         }\r
1681         break;\r
1682     } /* switch(HIWORD(wParam)) */\r
1683 \r
1684     return TRUE;\r
1685 }\r
1686 \r
1687 static LRESULT nc_handle_wm_help(HWND hwnd,\r
1688                                  UINT uMsg,\r
1689                                  WPARAM wParam,\r
1690                                  LPARAM lParam) {\r
1691     static DWORD ctxids[] = {\r
1692         NC_TS_CTRL_ID_MIN, IDH_NC_TABMAIN,\r
1693         NC_TS_CTRL_ID_MIN + 1, IDH_NC_TABBUTTON,\r
1694         NC_TS_CTRL_ID_MIN + 2, IDH_NC_TABBUTTON,\r
1695         NC_TS_CTRL_ID_MIN + 3, IDH_NC_TABBUTTON,\r
1696         NC_TS_CTRL_ID_MIN + 4, IDH_NC_TABBUTTON,\r
1697         NC_TS_CTRL_ID_MIN + 5, IDH_NC_TABBUTTON,\r
1698         NC_TS_CTRL_ID_MIN + 6, IDH_NC_TABBUTTON,\r
1699         NC_TS_CTRL_ID_MIN + 7, IDH_NC_TABBUTTON,\r
1700         IDOK, IDH_NC_OK,\r
1701         IDCANCEL, IDH_NC_CANCEL,\r
1702         IDC_NC_HELP, IDH_NC_HELP,\r
1703         IDC_NC_OPTIONS, IDH_NC_OPTIONS,\r
1704         IDC_NC_CREDTEXT, IDH_NC_CREDWND,\r
1705         0\r
1706     };\r
1707 \r
1708     HELPINFO * hlp;\r
1709     HWND hw = NULL;\r
1710     HWND hw_ctrl;\r
1711     khui_nc_wnd_data * d;\r
1712 \r
1713     d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);\r
1714 \r
1715     hlp = (HELPINFO *) lParam;\r
1716 \r
1717     if (d->nc->subtype != KMSG_CRED_NEW_CREDS &&\r
1718         d->nc->subtype != KMSG_CRED_PASSWORD)\r
1719         return TRUE;\r
1720 \r
1721     if (hlp->iContextType != HELPINFO_WINDOW)\r
1722         return TRUE;\r
1723 \r
1724     if (hlp->hItemHandle != NULL &&\r
1725         hlp->hItemHandle != hwnd) {\r
1726         DWORD id;\r
1727         int i;\r
1728 \r
1729         hw_ctrl =hlp->hItemHandle;\r
1730 \r
1731         id = GetWindowLong(hw_ctrl, GWL_ID);\r
1732         for (i=0; ctxids[i] != 0; i += 2)\r
1733             if (ctxids[i] == id)\r
1734                 break;\r
1735 \r
1736         if (ctxids[i] != 0)\r
1737             hw = khm_html_help(hw_ctrl,\r
1738                                ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?\r
1739                                 L"::popups_newcreds.txt":\r
1740                                 L"::popups_password.txt"),\r
1741                                HH_TP_HELP_WM_HELP,\r
1742                                (DWORD_PTR) ctxids);\r
1743     }\r
1744 \r
1745     if (hw == NULL) {\r
1746         khm_html_help(hwnd, NULL, HH_HELP_CONTEXT,\r
1747                       ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?\r
1748                        IDH_ACTION_NEW_ID: IDH_ACTION_PASSWD_ID));\r
1749     }\r
1750 \r
1751     return TRUE;\r
1752 }\r
1753 \r
1754 static LRESULT CALLBACK nc_window_proc(HWND hwnd,\r
1755                                        UINT uMsg,\r
1756                                        WPARAM wParam,\r
1757                                        LPARAM lParam)\r
1758 {\r
1759     switch(uMsg) {\r
1760     case WM_CREATE:\r
1761         return nc_handle_wm_create(hwnd, uMsg, wParam, lParam);\r
1762 \r
1763     case WM_DESTROY:\r
1764         return nc_handle_wm_destroy(hwnd, uMsg, wParam, lParam);\r
1765 \r
1766     case WM_COMMAND:\r
1767         return nc_handle_wm_command(hwnd, uMsg, wParam, lParam);\r
1768 \r
1769     case WM_MOVE:\r
1770     case WM_MOVING:\r
1771         return nc_handle_wm_moving(hwnd, uMsg, wParam, lParam);\r
1772 \r
1773     case WM_HELP:\r
1774         return nc_handle_wm_help(hwnd, uMsg, wParam, lParam);\r
1775 \r
1776     case KHUI_WM_NC_NOTIFY:\r
1777         return nc_handle_wm_nc_notify(hwnd, uMsg, wParam, lParam);\r
1778     }\r
1779 \r
1780     /* Note that this is technically a dialog box */\r
1781     return DefDlgProc(hwnd, uMsg, wParam, lParam);\r
1782 }\r
1783 \r
1784 void khm_register_newcredwnd_class(void)\r
1785 {\r
1786     WNDCLASSEX wcx;\r
1787 \r
1788     wcx.cbSize = sizeof(wcx);\r
1789     wcx.style = CS_DBLCLKS | CS_OWNDC;\r
1790     wcx.lpfnWndProc = nc_window_proc;\r
1791     wcx.cbClsExtra = 0;\r
1792     wcx.cbWndExtra = DLGWINDOWEXTRA + sizeof(LONG_PTR);\r
1793     wcx.hInstance = khm_hInstance;\r
1794     wcx.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));\r
1795     wcx.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);\r
1796     wcx.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);\r
1797     wcx.lpszMenuName = NULL;\r
1798     wcx.lpszClassName = KHUI_NEWCREDWND_CLASS;\r
1799     wcx.hIconSm = NULL;\r
1800 \r
1801     khui_newcredwnd_cls = RegisterClassEx(&wcx);\r
1802 }\r
1803 \r
1804 void khm_unregister_newcredwnd_class(void)\r
1805 {\r
1806     UnregisterClass((LPWSTR) khui_newcredwnd_cls, khm_hInstance);\r
1807 }\r
1808 \r
1809 HWND khm_create_newcredwnd(HWND parent, khui_new_creds * c)\r
1810 {\r
1811     wchar_t wtitle[256];\r
1812     HWND hwnd;\r
1813 \r
1814     if (c->window_title == NULL) {\r
1815         if (c->subtype == KMSG_CRED_PASSWORD)\r
1816             LoadString(khm_hInstance, \r
1817                        IDS_WT_PASSWORD,\r
1818                        wtitle,\r
1819                        ARRAYLENGTH(wtitle));\r
1820         else\r
1821             LoadString(khm_hInstance, \r
1822                        IDS_WT_NEW_CREDS,\r
1823                        wtitle,\r
1824                        ARRAYLENGTH(wtitle));\r
1825     }\r
1826 \r
1827     hwnd = CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_CONTEXTHELP,\r
1828                           MAKEINTATOM(khui_newcredwnd_cls),\r
1829                           ((c->window_title)?c->window_title: wtitle),\r
1830                           WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN,\r
1831                           0,0,400,400,    /* bogus values.  the window\r
1832                                              is going to resize and\r
1833                                              reposition itself\r
1834                                              anyway */\r
1835                           parent,\r
1836                           NULL,\r
1837                           khm_hInstance,\r
1838                           (LPVOID) c);\r
1839 \r
1840 #ifdef DEBUG\r
1841     assert(hwnd != NULL);\r
1842 #endif\r
1843 \r
1844     /* note that the window is not visible yet.  That's because, at\r
1845        this point we don't know what the panels are */\r
1846 \r
1847     return hwnd;\r
1848 }\r
1849 \r
1850 void khm_prep_newcredwnd(HWND hwnd)\r
1851 {\r
1852     SendMessage(hwnd, KHUI_WM_NC_NOTIFY, \r
1853                 MAKEWPARAM(0, WMNC_DIALOG_SETUP), 0);\r
1854 }\r
1855 \r
1856 void khm_show_newcredwnd(HWND hwnd)\r
1857 {\r
1858     /* add all the panels in and prep UI */\r
1859     SendMessage(hwnd, KHUI_WM_NC_NOTIFY, \r
1860                 MAKEWPARAM(0, WMNC_DIALOG_ACTIVATE), 0);\r
1861 }\r