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