2 * Copyright (c) 2005 Massachusetts Institute of Technology
\r
3 * Copyright (c) 2007 Secure Endpoints Inc.
\r
5 * Permission is hereby granted, free of charge, to any person
\r
6 * obtaining a copy of this software and associated documentation
\r
7 * files (the "Software"), to deal in the Software without
\r
8 * restriction, including without limitation the rights to use, copy,
\r
9 * modify, merge, publish, distribute, sublicense, and/or sell copies
\r
10 * of the Software, and to permit persons to whom the Software is
\r
11 * furnished to do so, subject to the following conditions:
\r
13 * The above copyright notice and this permission notice shall be
\r
14 * included in all copies or substantial portions of the Software.
\r
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
31 ATOM khui_newcredwnd_cls;
\r
35 nc_position_credtext(khui_nc_wnd_data * d);
\r
37 /* Common dialog procedure. Be careful. This is used by more than
\r
39 static INT_PTR CALLBACK
\r
40 nc_common_dlg_proc(HWND hwnd,
\r
48 khui_nc_wnd_data * d;
\r
50 d = (khui_nc_wnd_data *) lParam;
\r
52 #pragma warning(push)
\r
53 #pragma warning(disable: 4244)
\r
54 SetWindowLongPtr(hwnd, DWLP_USER, lParam);
\r
55 #pragma warning(pop)
\r
56 if (d->nc->subtype == KMSG_CRED_PASSWORD) {
\r
57 ShowWindow(GetDlgItem(hwnd, IDC_NC_OPTIONS),
\r
67 ctrl_id = LOWORD(wParam);
\r
68 if (ctrl_id < KHUI_CW_ID_MIN ||
\r
69 ctrl_id > KHUI_CW_ID_MAX) {
\r
70 /* pump it to the parent */
\r
71 PostMessage(GetParent(hwnd), WM_COMMAND, wParam, lParam);
\r
73 } /* else we allow the message to fall through and get
\r
74 passed into the identity provider's message
\r
80 /* someday this will be used to draw custom tab buttons. But
\r
84 khui_nc_wnd_data * d;
\r
86 LPDRAWITEMSTRUCT ds;
\r
88 d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, DWLP_USER);
\r
90 ds = (LPDRAWITEMSTRUCT) lParam;
\r
92 if(id >= NC_TS_CTRL_ID_MIN && id <= NC_TS_CTRL_ID_MAX) {
\r
93 /*TODO: custom draw the buttons */
\r
101 case KHUI_WM_NC_NOTIFY:
\r
103 khui_nc_wnd_data * d;
\r
104 d = (khui_nc_wnd_data *)(LONG_PTR)
\r
105 GetWindowLongPtr(hwnd, DWLP_USER);
\r
107 /* message sent by parent to notify us of something */
\r
108 switch(HIWORD(wParam)) {
\r
109 case WMNC_DIALOG_EXPAND:
\r
110 if(hwnd == d->dlg_main) {
\r
113 if(hw = GetDlgItem(hwnd, IDOK))
\r
114 ShowWindow(hw, SW_HIDE);
\r
115 if(hw = GetDlgItem(hwnd, IDCANCEL))
\r
116 ShowWindow(hw, SW_HIDE);
\r
117 if(hw = GetDlgItem(hwnd, IDC_NC_OPTIONS))
\r
118 ShowWindow(hw, SW_HIDE);
\r
120 d->r_credtext.bottom = d->r_area.bottom;
\r
122 nc_position_credtext(d);
\r
131 /* check if we have a wnd_data, and if so pass the message on to
\r
132 the identity provider callback. */
\r
134 khui_nc_wnd_data * d;
\r
136 d = (khui_nc_wnd_data *) (LONG_PTR)
\r
137 GetWindowLongPtr(hwnd, DWLP_USER);
\r
139 if (d && d->nc && d->nc->ident_cb) {
\r
140 return d->nc->ident_cb(d->nc, WMNC_IDENT_WMSG, hwnd, uMsg,
\r
149 nc_position_credtext(khui_nc_wnd_data * d)
\r
153 hw = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT);
\r
158 if (d->r_credtext.bottom < d->r_credtext.top + d->r_row.bottom * 2) {
\r
159 /* not enough room */
\r
160 if (d->nc->mode == KHUI_NC_MODE_MINI &&
\r
161 d->nc->subtype != KMSG_CRED_PASSWORD) {
\r
162 PostMessage(d->nc->hwnd, KHUI_WM_NC_NOTIFY,
\r
163 MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
\r
166 ShowWindow(hw, SW_HIDE);
\r
170 ShowWindow(hw, SW_SHOW);
\r
173 SetWindowPos(hw, NULL,
\r
174 d->r_credtext.left + d->r_n_input.left, /* x */
\r
175 d->r_credtext.top, /* y */
\r
176 d->r_n_input.right - d->r_n_input.left, /* width */
\r
177 d->r_credtext.bottom - d->r_credtext.top, /* height */
\r
178 SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
181 hw = GetDlgItem(d->dlg_main, IDC_NC_CREDTEXT_LABEL);
\r
183 SetWindowPos(hw, NULL,
\r
184 d->r_credtext.left + d->r_n_label.left, /* x */
\r
185 d->r_credtext.top, /* y */
\r
186 d->r_n_label.right - d->r_n_label.left, /* width */
\r
187 d->r_n_label.bottom - d->r_n_label.top, /* height */
\r
188 SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
192 /* sorts tab buttons */
\r
193 static int __cdecl
\r
194 nc_tab_sort_func(const void * v1, const void * v2)
\r
196 /* v1 and v2 and of type : khui_new_creds_by_type ** */
\r
197 khui_new_creds_by_type *t1, *t2;
\r
199 t1 = *((khui_new_creds_by_type **) v1);
\r
200 t2 = *((khui_new_creds_by_type **) v2);
\r
202 if(t1->ordinal != -1) {
\r
203 if(t2->ordinal != -1) {
\r
204 if(t1->ordinal == t2->ordinal)
\r
205 return wcscmp(t1->name, t2->name);
\r
207 /* safe to convert to an int here */
\r
208 return (int) (t1->ordinal - t2->ordinal);
\r
212 if(t2->ordinal != -1)
\r
214 else if (t1->name && t2->name)
\r
215 return wcscmp(t1->name, t2->name);
\r
222 nc_notify_types_async(khui_new_creds * c, UINT uMsg,
\r
223 WPARAM wParam, LPARAM lParam)
\r
227 for(i=0; i<c->n_types; i++) {
\r
228 PostMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);
\r
233 nc_notify_types(khui_new_creds * c, UINT uMsg,
\r
234 WPARAM wParam, LPARAM lParam)
\r
238 for(i=0; i<c->n_types; i++) {
\r
239 SendMessage(c->types[i]->hwnd_panel, uMsg, wParam, lParam);
\r
244 nc_clear_password_fields(khui_nc_wnd_data * d)
\r
247 khm_boolean need_sync = FALSE;
\r
249 khui_cw_lock_nc(d->nc);
\r
251 for (i=0; i < d->nc->n_prompts; i++) {
\r
252 if ((d->nc->prompts[i]->flags & KHUI_NCPROMPT_FLAG_HIDDEN) &&
\r
253 d->nc->prompts[i]->hwnd_edit) {
\r
254 SetWindowText(d->nc->prompts[i]->hwnd_edit,
\r
260 khui_cw_unlock_nc(d->nc);
\r
263 khui_cw_sync_prompt_values(d->nc);
\r
267 struct nc_enum_wnd_data {
\r
268 khui_nc_wnd_data * d;
\r
269 khm_boolean enable;
\r
274 nc_enum_wnd_proc(HWND hwnd,
\r
277 struct nc_enum_wnd_data * wd;
\r
279 wd = (struct nc_enum_wnd_data *) lParam;
\r
281 EnableWindow(hwnd, wd->enable);
\r
287 nc_enable_controls(khui_nc_wnd_data * d, khm_boolean enable)
\r
289 struct nc_enum_wnd_data wd;
\r
291 ZeroMemory(&wd, sizeof(wd));
\r
294 wd.enable = enable;
\r
296 EnumChildWindows(d->dlg_main, nc_enum_wnd_proc, (LPARAM) &wd);
\r
299 #define NC_MAXCCH_CREDTEXT 16384
\r
300 #define NC_MAXCB_CREDTEXT (NC_MAXCCH_CREDTEXT * sizeof(wchar_t))
\r
303 nc_update_credtext(khui_nc_wnd_data * d)
\r
305 wchar_t * ctbuf = NULL;
\r
307 BOOL okEnable = FALSE;
\r
308 BOOL validId = FALSE;
\r
312 ctbuf = PMALLOC(NC_MAXCB_CREDTEXT);
\r
314 assert(ctbuf != NULL);
\r
316 LoadString(khm_hInstance, IDS_NC_CREDTEXT_TABS, ctbuf, NC_MAXCCH_CREDTEXT);
\r
317 StringCchLength(ctbuf, NC_MAXCCH_CREDTEXT, &cch);
\r
319 nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
\r
320 MAKEWPARAM(0, WMNC_UPDATE_CREDTEXT), (LPARAM) d->nc);
\r
322 /* hopefully all the types have updated their credential texts */
\r
323 if(d->nc->n_identities == 1) {
\r
324 wchar_t main_fmt[256];
\r
325 wchar_t id_fmt[256];
\r
326 wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
\r
327 wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];
\r
331 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_ONE,
\r
332 main_fmt, (int) ARRAYLENGTH(main_fmt));
\r
334 cbbuf = sizeof(id_name);
\r
335 kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
\r
337 kcdb_identity_get_flags(d->nc->identities[0], &flags);
\r
339 if (flags & KCDB_IDENT_FLAG_INVALID) {
\r
340 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
\r
341 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
342 } else if(flags & KCDB_IDENT_FLAG_VALID) {
\r
343 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
\r
344 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
345 } else if(d->nc->subtype == KMSG_CRED_NEW_CREDS) {
\r
346 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_CHECKING,
\r
347 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
349 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
\r
350 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
353 StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
\r
355 StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t),
\r
356 main_fmt, id_string);
\r
358 if (flags & KCDB_IDENT_FLAG_VALID) {
\r
359 if (flags & KCDB_IDENT_FLAG_DEFAULT)
\r
360 LoadString(khm_hInstance, IDS_NC_ID_DEF,
\r
361 id_string, ARRAYLENGTH(id_string));
\r
362 else if (d->nc->set_default)
\r
363 LoadString(khm_hInstance, IDS_NC_ID_WDEF,
\r
364 id_string, ARRAYLENGTH(id_string));
\r
366 LoadString(khm_hInstance, IDS_NC_ID_NDEF,
\r
367 id_string, ARRAYLENGTH(id_string));
\r
369 StringCbCat(buf, NC_MAXCB_CREDTEXT - cch * sizeof(wchar_t),
\r
373 } else if(d->nc->n_identities > 1) {
\r
374 wchar_t *ids_string;
\r
375 khm_size cb_ids_string;
\r
377 wchar_t id_name[KCDB_IDENT_MAXCCH_NAME];
\r
378 wchar_t id_fmt[256];
\r
379 wchar_t id_string[KCDB_IDENT_MAXCCH_NAME + 256];
\r
381 wchar_t main_fmt[256];
\r
384 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_MANY,
\r
385 main_fmt, (int) ARRAYLENGTH(main_fmt));
\r
387 /* we are going to concatenate all the identity names into
\r
388 a comma separated string */
\r
390 /* d->nc->n_identities is at least 2 */
\r
391 ids_string = PMALLOC((KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) *
\r
392 (d->nc->n_identities - 1));
\r
394 (KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) *
\r
395 (d->nc->n_identities - 1);
\r
397 assert(ids_string != NULL);
\r
405 for(i=1; i<d->nc->n_identities; i++) {
\r
407 StringCbCat(ids_string, cb_ids_string, L",");
\r
412 cbbuf = sizeof(id_name);
\r
413 kcdb_identity_get_name(d->nc->identities[i], id_name, &cbbuf);
\r
414 kcdb_identity_get_flags(d->nc->identities[i], &flags);
\r
415 if(flags & KCDB_IDENT_FLAG_INVALID) {
\r
416 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
\r
417 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
418 } else if(flags & KCDB_IDENT_FLAG_VALID) {
\r
419 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
\r
420 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
422 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
\r
423 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
426 StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
\r
427 StringCbCat(ids_string, cb_ids_string, id_string);
\r
430 cbbuf = sizeof(id_name);
\r
431 kcdb_identity_get_name(d->nc->identities[0], id_name, &cbbuf);
\r
432 kcdb_identity_get_flags(d->nc->identities[0], &flags);
\r
433 if(flags & KCDB_IDENT_FLAG_INVALID) {
\r
434 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_INVALID,
\r
435 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
436 } else if(flags & KCDB_IDENT_FLAG_VALID) {
\r
437 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_VALID,
\r
438 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
440 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_UNCHECKED,
\r
441 id_fmt, (int) ARRAYLENGTH(id_fmt));
\r
443 StringCbPrintf(id_string, sizeof(id_string), id_fmt, id_name);
\r
445 StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t),
\r
446 main_fmt, id_string, ids_string);
\r
451 LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_NONE,
\r
452 buf, (int)(NC_MAXCCH_CREDTEXT - cch));
\r
455 /* now, append the credtext string from each of the cred types */
\r
461 cb = NC_MAXCB_CREDTEXT;
\r
464 for(i=0; i<d->nc->n_types; i++) {
\r
465 if(d->nc->types[i]->credtext != NULL) {
\r
466 StringCbCatEx(buf, cb,
\r
467 d->nc->types[i]->credtext,
\r
474 SetDlgItemText(d->dlg_main, IDC_NC_CREDTEXT, ctbuf);
\r
478 /* so depending on whether the primary identity was found to be
\r
479 invalid, we need to disable the Ok button and set the title to
\r
482 if(d->nc->n_identities > 0) {
\r
483 khm_int32 flags = 0;
\r
485 if(KHM_SUCCEEDED(kcdb_identity_get_flags(d->nc->identities[0],
\r
487 (flags & KCDB_IDENT_FLAG_VALID)) {
\r
492 if (d->nc->window_title == NULL) {
\r
494 wchar_t wpostfix[256];
\r
495 wchar_t wtitle[KCDB_IDENT_MAXCCH_NAME + 256];
\r
498 cbsize = sizeof(wtitle);
\r
499 kcdb_identity_get_name(d->nc->identities[0], wtitle, &cbsize);
\r
501 if (d->nc->subtype == KMSG_CRED_PASSWORD)
\r
502 LoadString(khm_hInstance, IDS_WTPOST_PASSWORD,
\r
503 wpostfix, (int) ARRAYLENGTH(wpostfix));
\r
505 LoadString(khm_hInstance, IDS_WTPOST_NEW_CREDS,
\r
506 wpostfix, (int) ARRAYLENGTH(wpostfix));
\r
508 StringCbCat(wtitle, sizeof(wtitle), wpostfix);
\r
510 SetWindowText(d->nc->hwnd, wtitle);
\r
512 wchar_t wtitle[256];
\r
514 if (d->nc->subtype == KMSG_CRED_PASSWORD)
\r
515 LoadString(khm_hInstance, IDS_WT_PASSWORD,
\r
516 wtitle, (int) ARRAYLENGTH(wtitle));
\r
518 LoadString(khm_hInstance, IDS_WT_NEW_CREDS,
\r
519 wtitle, (int) ARRAYLENGTH(wtitle));
\r
521 SetWindowText(d->nc->hwnd, wtitle);
\r
525 if (!(d->nc->response & KHUI_NC_RESPONSE_PROCESSING)) {
\r
527 d->nc->subtype == KMSG_CRED_PASSWORD) {
\r
528 /* TODO: check if all the required fields have valid values
\r
529 before enabling the Ok button */
\r
533 hw = GetDlgItem(d->dlg_main, IDOK);
\r
534 EnableWindow(hw, okEnable);
\r
535 hw = GetDlgItem(d->dlg_bb, IDOK);
\r
536 EnableWindow(hw, okEnable);
\r
540 #define CW_PARAM DWLP_USER
\r
543 nc_add_control_row(khui_nc_wnd_data * d,
\r
546 khui_control_size size);
\r
549 nc_handle_wm_create(HWND hwnd,
\r
554 LPCREATESTRUCT lpc;
\r
555 khui_new_creds * c;
\r
556 khui_nc_wnd_data * ncd;
\r
562 lpc = (LPCREATESTRUCT) lParam;
\r
564 ncd = PMALLOC(sizeof(*ncd));
\r
565 ZeroMemory(ncd, sizeof(*ncd));
\r
567 c = (khui_new_creds *) lpc->lpCreateParams;
\r
571 #pragma warning(push)
\r
572 #pragma warning(disable: 4244)
\r
573 SetWindowLongPtr(hwnd, CW_PARAM, (LONG_PTR) ncd);
\r
574 #pragma warning(pop)
\r
576 /* first try to create the main dialog panel */
\r
578 assert(c->subtype == KMSG_CRED_NEW_CREDS ||
\r
579 c->subtype == KMSG_CRED_PASSWORD);
\r
581 ncd->dlg_main = CreateDialogParam(khm_hInstance,
\r
582 MAKEINTRESOURCE(IDD_NC_PASSWORD),
\r
584 nc_common_dlg_proc,
\r
587 assert(ncd->dlg_main);
\r
596 /* pick out metrics for use by the custom prompter stuff */
\r
597 GetWindowRect(ncd->dlg_main, &r_main);
\r
599 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_PANEL);
\r
603 GetWindowRect(hw, &r_area);
\r
604 OffsetRect(&r_area,-r_main.left, -r_main.top);
\r
605 CopyRect(&ncd->r_area, &r_area);
\r
607 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW);
\r
611 GetWindowRect(hw, &r);
\r
612 CopyRect(&r_row, &r);
\r
613 OffsetRect(&r,-r.left, -r.top);
\r
614 CopyRect(&ncd->r_row, &r);
\r
616 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL);
\r
620 GetWindowRect(hw, &r);
\r
621 OffsetRect(&r,-r_row.left, -r_row.top);
\r
622 CopyRect(&ncd->r_n_label, &r);
\r
624 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT);
\r
628 GetWindowRect(hw, &r);
\r
629 OffsetRect(&r, -r_row.left, -r_row.top);
\r
630 CopyRect(&ncd->r_n_input, &r);
\r
632 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_ROW_LG);
\r
636 GetWindowRect(hw, &r_row);
\r
638 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_LABEL_LG);
\r
642 GetWindowRect(hw, &r);
\r
643 OffsetRect(&r, -r_row.left, -r_row.top);
\r
644 CopyRect(&ncd->r_e_label, &r);
\r
646 hw = GetDlgItem(ncd->dlg_main, IDC_NC_TPL_INPUT_LG);
\r
650 GetWindowRect(hw, &r);
\r
651 OffsetRect(&r, -r_row.left, -r_row.top);
\r
652 CopyRect(&ncd->r_e_input, &r);
\r
654 CopyRect(&ncd->r_credtext, &ncd->r_area);
\r
655 CopyRect(&ncd->r_idspec, &ncd->r_area);
\r
657 ncd->r_idspec.bottom = ncd->r_idspec.top;
\r
659 hw = GetDlgItem(ncd->dlg_main, IDC_NC_CREDTEXT);
\r
663 GetWindowRect(hw, &r);
\r
664 OffsetRect(&r, -r_main.left, -r_main.top);
\r
665 ncd->r_credtext.bottom = r.bottom;
\r
668 /* if the mode is 'mini'*/
\r
671 if(c->mode == KHUI_NC_MODE_MINI) {
\r
672 r.right = NCDLG_WIDTH;
\r
673 r.bottom = NCDLG_HEIGHT;
\r
675 r.right = NCDLG_WIDTH + NCDLG_BBAR_WIDTH;
\r
676 r.bottom = NCDLG_HEIGHT + NCDLG_TAB_HEIGHT;
\r
679 MapDialogRect(ncd->dlg_main, &r);
\r
681 ncd->r_main.left = 0;
\r
682 ncd->r_main.top = 0;
\r
683 ncd->r_main.right = NCDLG_WIDTH;
\r
684 ncd->r_main.bottom = NCDLG_HEIGHT;
\r
686 ncd->r_ts.left = 0;
\r
687 ncd->r_ts.top = ncd->r_main.bottom;
\r
688 ncd->r_ts.right = ncd->r_main.right;
\r
689 ncd->r_ts.bottom = ncd->r_ts.top + NCDLG_TAB_HEIGHT;
\r
691 ncd->r_bb.left = ncd->r_main.right;
\r
693 ncd->r_bb.right = ncd->r_bb.left + NCDLG_BBAR_WIDTH;
\r
694 ncd->r_bb.bottom = ncd->r_ts.bottom;
\r
696 MapDialogRect(ncd->dlg_main, &(ncd->r_main));
\r
697 MapDialogRect(ncd->dlg_main, &(ncd->r_ts));
\r
698 MapDialogRect(ncd->dlg_main, &(ncd->r_bb));
\r
700 /* center the new creds window over the main NetIDMgr window */
\r
701 width = r.right - r.left;
\r
702 height = r.bottom - r.top;
\r
704 /* adjust width and height to accomodate NC area */
\r
708 GetWindowRect(hwnd, &wr);
\r
709 GetClientRect(hwnd, &cr);
\r
711 /* the non-client and client areas have already been calculated
\r
712 at this point. We just use the difference to adjust the width
\r
714 width += (wr.right - wr.left) - (cr.right - cr.left);
\r
715 height += (wr.bottom - wr.top) - (cr.bottom - cr.top);
\r
718 GetWindowRect(lpc->hwndParent, &r);
\r
719 x = (r.right + r.left)/2 - width / 2;
\r
720 y = (r.top + r.bottom)/2 - height / 2;
\r
722 MoveWindow(hwnd, x, y, width, height, FALSE);
\r
724 SetWindowPos(ncd->dlg_main,
\r
728 ncd->r_main.right - ncd->r_main.left,
\r
729 ncd->r_main.bottom - ncd->r_main.top,
\r
730 SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
731 SWP_NOREDRAW | SWP_NOZORDER);
\r
733 /* IDD_NC_BBAR is the button bar that sits on the right of the
\r
734 dialog when the new creds window is in 'expanded' mode. */
\r
736 ncd->dlg_bb = CreateDialogParam(khm_hInstance,
\r
737 MAKEINTRESOURCE(IDD_NC_BBAR),
\r
739 nc_common_dlg_proc,
\r
743 assert(ncd->dlg_bb);
\r
746 SetWindowPos(ncd->dlg_bb,
\r
750 ncd->r_bb.right - ncd->r_bb.left,
\r
751 ncd->r_bb.bottom - ncd->r_bb.top,
\r
752 SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
753 SWP_NOREDRAW | SWP_NOZORDER);
\r
755 /* IDD_NC_TS is the tab strip that sits below the main panel when
\r
756 the new creds window is in 'expanded' mode */
\r
758 ncd->dlg_ts = CreateDialogParam(khm_hInstance,
\r
759 MAKEINTRESOURCE(IDD_NC_TS),
\r
761 nc_common_dlg_proc,
\r
765 assert(ncd->dlg_ts);
\r
768 SetWindowPos(ncd->dlg_ts,
\r
772 ncd->r_ts.right - ncd->r_ts.left,
\r
773 ncd->r_ts.bottom - ncd->r_ts.top,
\r
774 SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOOWNERZORDER |
\r
775 SWP_NOREDRAW | SWP_NOZORDER);
\r
777 if(c->mode == KHUI_NC_MODE_MINI) {
\r
778 /* hide and show stuff */
\r
779 ShowWindow(ncd->dlg_main, SW_SHOW);
\r
780 ShowWindow(ncd->dlg_bb, SW_HIDE);
\r
781 ShowWindow(ncd->dlg_ts, SW_HIDE);
\r
783 nc_position_credtext(ncd);
\r
786 /* hide and show stuff */
\r
787 ShowWindow(ncd->dlg_main, SW_SHOW);
\r
788 ShowWindow(ncd->dlg_bb, SW_SHOW);
\r
789 ShowWindow(ncd->dlg_ts, SW_SHOW);
\r
791 PostMessage(ncd->dlg_main, KHUI_WM_NC_NOTIFY,
\r
792 MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
\r
795 /* Call the identity provider callback to set the identity
\r
796 selector controls */
\r
797 c->ident_cb(c, WMNC_IDENT_INIT, NULL, 0, 0, (LPARAM) ncd->dlg_main);
\r
802 wchar_t wcaption[64];
\r
804 LoadString(khm_hInstance, IDS_NC_SETDEF, wcaption,
\r
805 ARRAYLENGTH(wcaption));
\r
807 /* Now create the set as default button */
\r
811 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX,
\r
814 (HMENU) NC_BN_SET_DEF_ID,
\r
818 nc_add_control_row(ncd, NULL, hw, KHUI_CTRLSIZE_HALF);
\r
821 /* we defer the creation of the tab buttons for later */
\r
823 /* bring the window to the top, if necessary */
\r
824 if (KHM_SUCCEEDED(khc_read_int32(NULL,
\r
825 L"CredWindow\\Windows\\NewCred\\ForceToTop",
\r
828 !khm_is_dialog_active()) {
\r
830 /* if the main window is not visible, then the SetWindowPos()
\r
831 call is sufficient to bring the new creds window to the
\r
832 top. However, if the main window is visible but not
\r
833 active, the main window needs to be activated before a
\r
834 child window can be activated. */
\r
835 khm_activate_main_window();
\r
837 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0,
\r
838 (SWP_NOMOVE | SWP_NOSIZE));
\r
842 /* add this to the dialog chain */
\r
843 khm_add_dialog(hwnd);
\r
849 nc_add_control_row(khui_nc_wnd_data * d,
\r
852 khui_control_size size)
\r
859 hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
\r
860 SendMessage(label, WM_SETFONT, (WPARAM) hf, FALSE);
\r
861 SendMessage(input, WM_SETFONT, (WPARAM) hf, FALSE);
\r
863 CopyRect(&r_row, &d->r_row);
\r
864 OffsetRect(&r_row, d->r_idspec.left, d->r_idspec.bottom);
\r
866 if (size == KHUI_CTRLSIZE_SMALL) {
\r
867 CopyRect(&r_label, &d->r_n_label);
\r
868 CopyRect(&r_input, &d->r_n_input);
\r
869 OffsetRect(&r_label, r_row.left, r_row.top);
\r
870 OffsetRect(&r_input, r_row.left, r_row.top);
\r
871 } else if (size == KHUI_CTRLSIZE_HALF) {
\r
872 CopyRect(&r_label, &d->r_e_label);
\r
873 CopyRect(&r_input, &d->r_e_input);
\r
874 OffsetRect(&r_label, r_row.left, r_row.top);
\r
875 OffsetRect(&r_input, r_row.left, r_row.top);
\r
876 } else if (size == KHUI_CTRLSIZE_FULL) {
\r
877 CopyRect(&r_label, &d->r_n_label);
\r
878 r_label.right = d->r_row.right;
\r
879 CopyRect(&r_input, &d->r_n_input);
\r
880 OffsetRect(&r_input, r_row.left, r_row.top);
\r
881 OffsetRect(&r_input, 0, r_input.bottom);
\r
882 r_row.bottom += r_input.bottom;
\r
883 OffsetRect(&r_label, r_row.left, r_row.top);
\r
885 SetRectEmpty(&r_label);
\r
886 SetRectEmpty(&r_input);
\r
894 SetWindowPos(label,
\r
895 ((d->hwnd_last_idspec != NULL)?
\r
896 d->hwnd_last_idspec:
\r
898 r_label.left, r_label.top,
\r
899 r_label.right - r_label.left,
\r
900 r_label.bottom - r_label.top,
\r
901 SWP_DEFERERASE | SWP_NOACTIVATE |
\r
902 SWP_NOOWNERZORDER);
\r
905 SetWindowPos(input,
\r
906 (label ? label : ((d->hwnd_last_idspec != NULL)?
\r
907 d->hwnd_last_idspec:
\r
909 r_input.left, r_input.top,
\r
910 r_input.right - r_input.left,
\r
911 r_input.bottom - r_input.top,
\r
912 SWP_DEFERERASE | SWP_NOACTIVATE |
\r
913 SWP_NOOWNERZORDER);
\r
915 d->hwnd_last_idspec = input;
\r
917 d->r_idspec.bottom = r_row.bottom;
\r
919 d->r_credtext.top = r_row.bottom;
\r
921 nc_position_credtext(d);
\r
926 nc_handle_wm_destroy(HWND hwnd,
\r
931 khui_nc_wnd_data * d;
\r
934 /* remove self from dialog chain */
\r
935 khm_del_dialog(hwnd);
\r
937 d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
\r
939 d->nc->ident_cb(d->nc, WMNC_IDENT_EXIT, NULL, 0, 0, 0);
\r
941 if(d->hwnd_tc_main)
\r
942 DestroyWindow(d->hwnd_tc_main);
\r
943 for(i=0;i<d->nc->n_types;i++) {
\r
944 if(d->nc->types[i]->hwnd_tc) {
\r
945 DestroyWindow(d->nc->types[i]->hwnd_tc);
\r
946 d->nc->types[i]->hwnd_tc = NULL;
\r
951 DestroyWindow(d->dlg_bb);
\r
953 DestroyWindow(d->dlg_main);
\r
955 DestroyWindow(d->dlg_ts);
\r
958 d->dlg_main = NULL;
\r
967 nc_handle_wm_command(HWND hwnd,
\r
972 khui_nc_wnd_data * d;
\r
975 d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
\r
977 switch(HIWORD(wParam)) {
\r
979 switch(LOWORD(wParam)) {
\r
982 d->nc->result = KHUI_NC_RESULT_PROCESS;
\r
987 /* the default value for d->nc->result is set to
\r
988 KHUI_NC_RESULT_CANCEL */
\r
989 d->nc->response = KHUI_NC_RESPONSE_PROCESSING;
\r
991 nc_enable_controls(d, FALSE);
\r
993 nc_notify_types(d->nc,
\r
994 KHUI_WM_NC_NOTIFY,
\r
995 MAKEWPARAM(0,WMNC_DIALOG_PREPROCESS),
\r
998 khui_cw_sync_prompt_values(d->nc);
\r
1000 khm_cred_dispatch_process_message(d->nc);
\r
1002 /* we won't know whether to abort or not until we get
\r
1003 feedback from the plugins, even if the command was
\r
1008 hw = GetDlgItem(d->dlg_main, IDOK);
\r
1009 EnableWindow(hw, FALSE);
\r
1010 hw = GetDlgItem(d->dlg_main, IDCANCEL);
\r
1011 EnableWindow(hw, FALSE);
\r
1012 hw = GetDlgItem(d->dlg_main, IDC_NC_OPTIONS);
\r
1013 EnableWindow(hw, FALSE);
\r
1014 hw = GetDlgItem(d->dlg_bb, IDOK);
\r
1015 EnableWindow(hw, FALSE);
\r
1016 hw = GetDlgItem(d->dlg_bb, IDCANCEL);
\r
1017 EnableWindow(hw, FALSE);
\r
1022 khm_html_help(hwnd, NULL, HH_HELP_CONTEXT, IDH_ACTION_NEW_ID);
\r
1025 case IDC_NC_OPTIONS:
\r
1026 /* the Options button in the main window was clicked. we
\r
1027 respond by expanding the dialog. */
\r
1028 PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
\r
1029 MAKEWPARAM(0, WMNC_DIALOG_EXPAND), 0);
\r
1032 case IDC_NC_CREDTEXT: /* credtext link activated */
\r
1034 khui_htwnd_link * l;
\r
1035 wchar_t sid[KHUI_MAXCCH_HTLINK_FIELD];
\r
1036 wchar_t sparam[KHUI_MAXCCH_HTLINK_FIELD];
\r
1039 l = (khui_htwnd_link *) lParam;
\r
1041 /* do we have a valid link? */
\r
1042 if(l->id == NULL || l->id_len >= ARRAYLENGTH(sid))
\r
1043 return TRUE; /* nope */
\r
1045 StringCchCopyN(sid, ARRAYLENGTH(sid), l->id, l->id_len);
\r
1046 sid[l->id_len] = L'\0'; /* just make sure */
\r
1048 if(l->param != NULL &&
\r
1049 l->param_len < ARRAYLENGTH(sparam) &&
\r
1050 l->param_len > 0) {
\r
1052 StringCchCopyN(sparam, ARRAYLENGTH(sparam),
\r
1053 l->param, l->param_len);
\r
1054 sparam[l->param_len] = L'\0';
\r
1057 sparam[0] = L'\0';
\r
1060 /* If the ID is of the form '<credtype>:<link_tag>'
\r
1061 and <credtype> is a valid name of a credentials
\r
1062 type that is participating in the credentials
\r
1063 acquisition process, then we forward the message to
\r
1064 the panel that is providing the UI for that cred
\r
1065 type. We also switch to that panel first, unless
\r
1066 the link is of the form '<credtype>:!<link_tag>'. */
\r
1068 colon = wcschr(sid, L':');
\r
1069 if (colon != NULL) {
\r
1070 khm_int32 credtype;
\r
1071 khui_new_creds_by_type * t;
\r
1074 if (KHM_SUCCEEDED(kcdb_credtype_get_id(sid, &credtype)) &&
\r
1075 KHM_SUCCEEDED(khui_cw_find_type(d->nc, credtype, &t))){
\r
1078 if (t->ordinal != d->ctab &&
\r
1079 *(colon + 1) != L'!')
\r
1081 KHUI_WM_NC_NOTIFY,
\r
1082 MAKEWPARAM(t->ordinal,
\r
1083 WMNC_DIALOG_SWITCH_PANEL),
\r
1086 return SendMessage(t->hwnd_panel,
\r
1087 KHUI_WM_NC_NOTIFY,
\r
1088 MAKEWPARAM(0, WMNC_CREDTEXT_LINK),
\r
1095 /* if it was for us, then we need to process the message */
\r
1096 if(!_wcsicmp(sid, CTLINKID_SWITCH_PANEL)) {
\r
1097 khm_int32 credtype;
\r
1098 khui_new_creds_by_type * t;
\r
1100 if (KHM_SUCCEEDED(kcdb_credtype_get_id(sparam,
\r
1102 KHM_SUCCEEDED(khui_cw_find_type(d->nc,
\r
1104 if (t->ordinal != d->ctab)
\r
1106 KHUI_WM_NC_NOTIFY,
\r
1107 MAKEWPARAM(t->ordinal,
\r
1108 WMNC_DIALOG_SWITCH_PANEL),
\r
1111 } else if (!_wcsicmp(sid, L"NotDef")) {
\r
1112 d->nc->set_default = FALSE;
\r
1113 nc_update_credtext(d);
\r
1114 } else if (!_wcsicmp(sid, L"MakeDef")) {
\r
1115 d->nc->set_default = TRUE;
\r
1116 nc_update_credtext(d);
\r
1122 case NC_BN_SET_DEF_ID:
\r
1124 d->nc->set_default =
\r
1125 (IsDlgButtonChecked(d->dlg_main, NC_BN_SET_DEF_ID)
\r
1132 /* if one of the tab strip buttons were pressed, then
\r
1133 we should switch to that panel */
\r
1134 id = LOWORD(wParam);
\r
1135 if(id >= NC_TS_CTRL_ID_MIN && id <= NC_TS_CTRL_ID_MAX) {
\r
1136 id -= NC_TS_CTRL_ID_MIN;
\r
1137 PostMessage(hwnd, KHUI_WM_NC_NOTIFY,
\r
1138 MAKEWPARAM(id, WMNC_DIALOG_SWITCH_PANEL),0);
\r
1148 static LRESULT nc_handle_wm_moving(HWND hwnd,
\r
1153 khui_nc_wnd_data * d;
\r
1155 d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
\r
1157 nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
\r
1158 MAKEWPARAM(0, WMNC_DIALOG_MOVE), (LPARAM) d->nc);
\r
1163 static LRESULT nc_handle_wm_nc_notify(HWND hwnd,
\r
1168 khui_nc_wnd_data * d;
\r
1170 int width, height;
\r
1173 d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
\r
1175 switch(HIWORD(wParam)) {
\r
1177 case WMNC_DIALOG_SWITCH_PANEL:
\r
1178 id = LOWORD(wParam);
\r
1179 if(id >= 0 && id <= d->nc->n_types) {
\r
1180 /* one of the tab buttons were pressed */
\r
1181 if(d->ctab == id) {
\r
1182 return TRUE; /* nothign to do */
\r
1185 if(d->ctab == 0) {
\r
1186 ShowWindow(d->dlg_main, SW_HIDE);
\r
1187 SendMessage(d->hwnd_tc_main,
\r
1188 BM_SETCHECK, BST_UNCHECKED, 0);
\r
1190 ShowWindow(d->nc->types[d->ctab - 1]->hwnd_panel, SW_HIDE);
\r
1191 SendMessage(d->nc->types[d->ctab - 1]->hwnd_tc,
\r
1192 BM_SETCHECK, BST_UNCHECKED, 0);
\r
1197 if(d->ctab == 0) {
\r
1198 ShowWindow(d->dlg_main, SW_SHOW);
\r
1199 SendMessage(d->hwnd_tc_main,
\r
1200 BM_SETCHECK, BST_CHECKED, 0);
\r
1202 ShowWindow(d->nc->types[id - 1]->hwnd_panel, SW_SHOW);
\r
1203 SendMessage(d->nc->types[id - 1]->hwnd_tc,
\r
1204 BM_SETCHECK, BST_CHECKED, 0);
\r
1208 if(d->nc->mode == KHUI_NC_MODE_EXPANDED)
\r
1213 case WMNC_DIALOG_EXPAND:
\r
1214 /* we are expanding the dialog box */
\r
1216 /* nothing to do? */
\r
1217 if (d->nc->mode == KHUI_NC_MODE_EXPANDED)
\r
1220 d->nc->mode = KHUI_NC_MODE_EXPANDED;
\r
1224 r.right = NCDLG_WIDTH + NCDLG_BBAR_WIDTH;
\r
1225 r.bottom = NCDLG_HEIGHT + NCDLG_TAB_HEIGHT;
\r
1227 MapDialogRect(d->dlg_main, &r);
\r
1229 width = r.right - r.left;
\r
1230 height = r.bottom - r.top;
\r
1232 /* adjust width and height to accomodate NC area */
\r
1236 GetWindowRect(hwnd, &wr);
\r
1237 GetClientRect(hwnd, &cr);
\r
1239 /* the non-client and client areas have already been
\r
1240 calculated at this point. We just use the difference
\r
1241 to adjust the width and height */
\r
1242 width += (wr.right - wr.left) - (cr.right - cr.left);
\r
1243 height += (wr.bottom - wr.top) - (cr.bottom - cr.top);
\r
1246 SendMessage(d->dlg_main,
\r
1247 KHUI_WM_NC_NOTIFY,
\r
1248 MAKEWPARAM(0,WMNC_DIALOG_EXPAND),
\r
1251 SetWindowPos(hwnd,
\r
1255 SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOOWNERZORDER |
\r
1258 ShowWindow(d->dlg_bb, SW_SHOW);
\r
1259 ShowWindow(d->dlg_ts, SW_SHOW);
\r
1262 case WMNC_DIALOG_SETUP:
\r
1263 if(d->nc->n_types > 0) {
\r
1265 for(i=0; i < d->nc->n_types;i++) {
\r
1267 if (d->nc->types[i]->dlg_proc == NULL) {
\r
1268 d->nc->types[i]->hwnd_panel = NULL;
\r
1270 /* Create the dialog panel */
\r
1271 d->nc->types[i]->hwnd_panel =
\r
1272 CreateDialogParam(d->nc->types[i]->h_module,
\r
1273 d->nc->types[i]->dlg_template,
\r
1275 d->nc->types[i]->dlg_proc,
\r
1279 assert(d->nc->types[i]->hwnd_panel);
\r
1286 case WMNC_DIALOG_ACTIVATE:
\r
1288 int x,y,width,height;
\r
1291 wchar_t wbuf[256];
\r
1294 /* now we create all the tab strip controls */
\r
1297 r.right = NCDLG_TAB_WIDTH;
\r
1298 r.bottom = NCDLG_TAB_HEIGHT;
\r
1299 MapDialogRect(d->dlg_main, &r);
\r
1301 width = r.right - r.left;
\r
1302 height = r.bottom - r.top;
\r
1307 id = NC_TS_CTRL_ID_MIN;
\r
1309 /* if we have too many buttons than would fit on the
\r
1310 button bar, we have to adjust the width of the buttons.
\r
1311 Of course, having too many of them would be bad and
\r
1312 make the buttons fairly useless. This is just an
\r
1313 interim measure. */
\r
1315 khui_cw_lock_nc(d->nc);
\r
1317 GetWindowRect(d->dlg_ts, &r);
\r
1318 if (x + width * (d->nc->n_types + 1) > (khm_size) (r.right - r.left)) {
\r
1319 width = (int)(((r.right - r.left) - x) / (d->nc->n_types + 1));
\r
1322 /* first, the control for the main panel */
\r
1323 LoadString(khm_hInstance, IDS_NC_IDENTITY,
\r
1324 wbuf, ARRAYLENGTH(wbuf));
\r
1326 d->hwnd_tc_main =
\r
1327 CreateWindow(L"BUTTON",
\r
1329 WS_VISIBLE | WS_CHILD | WS_TABSTOP |
\r
1330 BS_PUSHLIKE | BS_CHECKBOX | BS_TEXT,
\r
1333 (HMENU)(INT_PTR) id,
\r
1337 hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
\r
1338 SendMessage(d->hwnd_tc_main, WM_SETFONT, (WPARAM) hf, 0);
\r
1339 SendMessage(d->hwnd_tc_main, BM_SETCHECK, BST_CHECKED, 0);
\r
1344 if(d->nc->n_types > 0) {
\r
1346 /* we should sort the tabs first */
\r
1347 qsort(d->nc->types,
\r
1349 sizeof(*(d->nc->types)),
\r
1350 nc_tab_sort_func);
\r
1352 for(i=0; i < d->nc->n_types;i++) {
\r
1353 wchar_t * name = NULL;
\r
1355 d->nc->types[i]->ordinal = i + 1;
\r
1357 if(d->nc->types[i]->name)
\r
1358 name = d->nc->types[i]->name;
\r
1362 if(kcdb_credtype_describe
\r
1363 (d->nc->types[i]->type,
\r
1366 KCDB_TS_SHORT) == KHM_ERROR_TOO_LONG) {
\r
1368 name = PMALLOC(cbsize);
\r
1369 kcdb_credtype_describe(d->nc->types[i]->type,
\r
1381 d->nc->types[i]->hwnd_tc =
\r
1382 CreateWindow(L"BUTTON",
\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
1390 (HMENU)(INT_PTR) id,
\r
1394 SendMessage(d->nc->types[i]->hwnd_tc, WM_SETFONT,
\r
1398 if(d->nc->types[i]->flags & KHUI_NCT_FLAG_DISABLED)
\r
1399 SendMessage(d->nc->types[i]->hwnd_tc,
\r
1402 LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_DISABLED)));
\r
1404 SendMessage(d->nc->types[i]->hwnd_tc,
\r
1407 LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_ENABLED)));
\r
1413 if(!(d->nc->types[i]->name))
\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
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
1431 khui_cw_unlock_nc(d->nc);
\r
1433 nc_update_credtext(d);
\r
1435 ShowWindow(hwnd, SW_SHOWNOACTIVATE);
\r
1438 if (d->nc->n_identities == 0)
\r
1444 case WMNC_IDENTITY_CHANGE:
\r
1446 BOOL okEnable = FALSE;
\r
1448 nc_notify_types(d->nc, KHUI_WM_NC_NOTIFY,
\r
1449 MAKEWPARAM(0, WMNC_IDENTITY_CHANGE), (LPARAM) d->nc);
\r
1451 if (d->nc->subtype == KMSG_CRED_NEW_CREDS &&
\r
1452 d->nc->n_identities > 0 &&
\r
1453 d->nc->identities[0]) {
\r
1456 kcdb_identity_get_flags(d->nc->identities[0], &f);
\r
1458 if (!(f & KCDB_IDENT_FLAG_DEFAULT)) {
\r
1459 d->nc->set_default = FALSE;
\r
1463 nc_update_credtext(d);
\r
1468 case WMNC_TYPE_STATE:
\r
1470 case WMNC_UPDATE_CREDTEXT:
\r
1471 nc_update_credtext(d);
\r
1474 case WMNC_CLEAR_PROMPTS:
\r
1478 khui_cw_lock_nc(d->nc);
\r
1480 if(d->hwnd_banner != NULL) {
\r
1481 DestroyWindow(d->hwnd_banner);
\r
1482 d->hwnd_banner = NULL;
\r
1485 if(d->hwnd_name != NULL) {
\r
1486 DestroyWindow(d->hwnd_name);
\r
1487 d->hwnd_name = NULL;
\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
1496 if(d->nc->prompts[i]->hwnd_edit != NULL)
\r
1497 DestroyWindow(d->nc->prompts[i]->hwnd_edit);
\r
1500 d->nc->prompts[i]->hwnd_static = NULL;
\r
1501 d->nc->prompts[i]->hwnd_edit = NULL;
\r
1504 khui_cw_unlock_nc(d->nc);
\r
1506 d->r_credtext.top = d->r_idspec.bottom;
\r
1508 nc_position_credtext(d);
\r
1512 case WMNC_SET_PROMPTS:
\r
1519 BOOL use_large_lables = FALSE;
\r
1521 /* we assume that WMNC_CLEAR_PROMPTS has already been
\r
1524 khui_cw_lock_nc(d->nc);
\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
1532 hw = GetDlgItem(d->dlg_main, IDC_NC_PASSWORD);
\r
1533 EnableWindow(hw, TRUE);
\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
1539 khui_cw_unlock_nc(d->nc);
\r
1543 /* for everything else */
\r
1545 /* hide the stock password controls */
\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
1554 y = d->r_idspec.bottom;
\r
1556 hf = (HFONT) SendMessage(d->dlg_main, WM_GETFONT, 0, 0);
\r
1558 if (d->nc->pname != NULL) {
\r
1564 SS_SUNKEN | WS_CHILD,
\r
1565 d->r_area.left, y,
\r
1567 d->r_n_label.bottom - d->r_n_label.top,
\r
1576 d->hwnd_name = hw;
\r
1577 SendMessage(hw, WM_SETFONT, (WPARAM)hf, (LPARAM) TRUE);
\r
1578 ShowWindow(hw, SW_SHOW);
\r
1580 y += d->r_n_label.bottom - d->r_n_label.top;
\r
1583 if (d->nc->banner != NULL) {
\r
1590 d->r_area.left, y,
\r
1591 d->r_row.right, d->r_row.bottom,
\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
1605 hw_prev = d->hwnd_last_idspec;
\r
1607 hdc = GetWindowDC(d->dlg_main);
\r
1608 hfold = SelectObject(hdc,hf);
\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
1617 GetTextExtentPoint32(hdc,
\r
1618 d->nc->prompts[i]->prompt,
\r
1619 (int) wcslen(d->nc->prompts[i]->prompt),
\r
1622 if(s.cx >= d->r_n_label.right - d->r_n_label.left) {
\r
1623 use_large_lables = TRUE;
\r
1629 for(i=0; i<d->nc->n_prompts; i++) {
\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
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
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
1650 /* oops. the prompt doesn't fit in our
\r
1651 controls. we need to use up two lines */
\r
1653 pr.right = d->r_row.right;
\r
1655 pr.bottom = d->r_n_label.bottom -
\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
1663 SetRectEmpty(&pr);
\r
1664 CopyRect(&er, &d->r_n_input);
\r
1665 dy = d->r_row.bottom;
\r
1668 if(IsRectEmpty(&pr)) {
\r
1669 d->nc->prompts[i]->hwnd_static = NULL;
\r
1671 OffsetRect(&pr, d->r_area.left, y);
\r
1673 hw = CreateWindowEx
\r
1676 d->nc->prompts[i]->prompt,
\r
1679 pr.right - pr.left, pr.bottom - pr.top,
\r
1688 SendMessage(hw, WM_SETFONT,
\r
1689 (WPARAM) hf, (LPARAM) TRUE);
\r
1691 SetWindowPos(hw, hw_prev,
\r
1693 SWP_NOACTIVATE | SWP_NOMOVE |
\r
1694 SWP_NOOWNERZORDER | SWP_NOSIZE |
\r
1697 d->nc->prompts[i]->hwnd_static = hw;
\r
1701 OffsetRect(&er, d->r_area.left, y);
\r
1703 hw = CreateWindowEx
\r
1706 (d->nc->prompts[i]->def ?
\r
1707 d->nc->prompts[i]->def : L""),
\r
1708 WS_CHILD | WS_TABSTOP |
\r
1710 ((d->nc->prompts[i]->flags &
\r
1711 KHUI_NCPROMPT_FLAG_HIDDEN)? ES_PASSWORD:0),
\r
1713 er.right - er.left, er.bottom - er.top,
\r
1723 SendMessage(hw, WM_SETFONT,
\r
1724 (WPARAM) hf, (LPARAM) TRUE);
\r
1726 SetWindowPos(hw, hw_prev,
\r
1728 SWP_NOACTIVATE | SWP_NOMOVE |
\r
1729 SWP_NOOWNERZORDER | SWP_NOSIZE |
\r
1732 SendMessage(hw, EM_SETLIMITTEXT,
\r
1733 KHUI_MAXCCH_PROMPT_VALUE -1,
\r
1736 d->nc->prompts[i]->hwnd_edit = hw;
\r
1743 if (d->nc->n_prompts > 0 &&
\r
1744 d->nc->prompts[0]->hwnd_edit) {
\r
1746 SetFocus(d->nc->prompts[0]->hwnd_edit);
\r
1750 SelectObject(hdc, hfold);
\r
1751 ReleaseDC(d->dlg_main, hdc);
\r
1753 khui_cw_unlock_nc(d->nc);
\r
1755 d->r_credtext.top = y;
\r
1757 nc_position_credtext(d);
\r
1761 case WMNC_DIALOG_PROCESS_COMPLETE:
\r
1763 khui_new_creds * nc;
\r
1767 nc->response &= ~KHUI_NC_RESPONSE_PROCESSING;
\r
1769 if(nc->response & KHUI_NC_RESPONSE_NOEXIT) {
\r
1772 nc_enable_controls(d, TRUE);
\r
1775 nc->result = KHUI_NC_RESULT_CANCEL;
\r
1777 hw = GetDlgItem(d->dlg_main, IDOK);
\r
1778 EnableWindow(hw, TRUE);
\r
1779 hw = GetDlgItem(d->dlg_main, IDCANCEL);
\r
1780 EnableWindow(hw, TRUE);
\r
1781 hw = GetDlgItem(d->dlg_main, IDC_NC_OPTIONS);
\r
1782 EnableWindow(hw, TRUE);
\r
1783 hw = GetDlgItem(d->dlg_bb, IDOK);
\r
1784 EnableWindow(hw, TRUE);
\r
1785 hw = GetDlgItem(d->dlg_bb, IDCANCEL);
\r
1786 EnableWindow(hw, TRUE);
\r
1788 nc_clear_password_fields(d);
\r
1793 DestroyWindow(hwnd);
\r
1795 kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, (void *) nc);
\r
1799 /* MUST be called with SendMessage */
\r
1800 case WMNC_ADD_CONTROL_ROW:
\r
1802 khui_control_row * row;
\r
1804 row = (khui_control_row *) lParam;
\r
1807 assert(row->label);
\r
1808 assert(row->input);
\r
1811 nc_add_control_row(d, row->label, row->input, row->size);
\r
1814 } /* switch(HIWORD(wParam)) */
\r
1819 static LRESULT nc_handle_wm_help(HWND hwnd,
\r
1823 static DWORD ctxids[] = {
\r
1824 NC_TS_CTRL_ID_MIN, IDH_NC_TABMAIN,
\r
1825 NC_TS_CTRL_ID_MIN + 1, IDH_NC_TABBUTTON,
\r
1826 NC_TS_CTRL_ID_MIN + 2, IDH_NC_TABBUTTON,
\r
1827 NC_TS_CTRL_ID_MIN + 3, IDH_NC_TABBUTTON,
\r
1828 NC_TS_CTRL_ID_MIN + 4, IDH_NC_TABBUTTON,
\r
1829 NC_TS_CTRL_ID_MIN + 5, IDH_NC_TABBUTTON,
\r
1830 NC_TS_CTRL_ID_MIN + 6, IDH_NC_TABBUTTON,
\r
1831 NC_TS_CTRL_ID_MIN + 7, IDH_NC_TABBUTTON,
\r
1833 IDCANCEL, IDH_NC_CANCEL,
\r
1834 IDC_NC_HELP, IDH_NC_HELP,
\r
1835 IDC_NC_OPTIONS, IDH_NC_OPTIONS,
\r
1836 IDC_NC_CREDTEXT, IDH_NC_CREDWND,
\r
1843 khui_nc_wnd_data * d;
\r
1845 d = (khui_nc_wnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, CW_PARAM);
\r
1847 hlp = (HELPINFO *) lParam;
\r
1849 if (d->nc->subtype != KMSG_CRED_NEW_CREDS &&
\r
1850 d->nc->subtype != KMSG_CRED_PASSWORD)
\r
1853 if (hlp->iContextType != HELPINFO_WINDOW)
\r
1856 if (hlp->hItemHandle != NULL &&
\r
1857 hlp->hItemHandle != hwnd) {
\r
1861 hw_ctrl =hlp->hItemHandle;
\r
1863 id = GetWindowLong(hw_ctrl, GWL_ID);
\r
1864 for (i=0; ctxids[i] != 0; i += 2)
\r
1865 if (ctxids[i] == id)
\r
1868 if (ctxids[i] != 0)
\r
1869 hw = khm_html_help(hw_ctrl,
\r
1870 ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?
\r
1871 L"::popups_newcreds.txt":
\r
1872 L"::popups_password.txt"),
\r
1873 HH_TP_HELP_WM_HELP,
\r
1874 (DWORD_PTR) ctxids);
\r
1878 khm_html_help(hwnd, NULL, HH_HELP_CONTEXT,
\r
1879 ((d->nc->subtype == KMSG_CRED_NEW_CREDS)?
\r
1880 IDH_ACTION_NEW_ID: IDH_ACTION_PASSWD_ID));
\r
1886 static LRESULT CALLBACK nc_window_proc(HWND hwnd,
\r
1893 return nc_handle_wm_create(hwnd, uMsg, wParam, lParam);
\r
1896 return nc_handle_wm_destroy(hwnd, uMsg, wParam, lParam);
\r
1899 return nc_handle_wm_command(hwnd, uMsg, wParam, lParam);
\r
1903 return nc_handle_wm_moving(hwnd, uMsg, wParam, lParam);
\r
1906 return nc_handle_wm_help(hwnd, uMsg, wParam, lParam);
\r
1908 case KHUI_WM_NC_NOTIFY:
\r
1909 return nc_handle_wm_nc_notify(hwnd, uMsg, wParam, lParam);
\r
1912 /* Note that this is technically a dialog box */
\r
1913 return DefDlgProc(hwnd, uMsg, wParam, lParam);
\r
1916 void khm_register_newcredwnd_class(void)
\r
1920 wcx.cbSize = sizeof(wcx);
\r
1921 wcx.style = CS_DBLCLKS | CS_OWNDC;
\r
1922 wcx.lpfnWndProc = nc_window_proc;
\r
1923 wcx.cbClsExtra = 0;
\r
1924 wcx.cbWndExtra = DLGWINDOWEXTRA + sizeof(LONG_PTR);
\r
1925 wcx.hInstance = khm_hInstance;
\r
1926 wcx.hIcon = LoadIcon(khm_hInstance, MAKEINTRESOURCE(IDI_MAIN_APP));
\r
1927 wcx.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
\r
1928 wcx.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
\r
1929 wcx.lpszMenuName = NULL;
\r
1930 wcx.lpszClassName = KHUI_NEWCREDWND_CLASS;
\r
1931 wcx.hIconSm = NULL;
\r
1933 khui_newcredwnd_cls = RegisterClassEx(&wcx);
\r
1936 void khm_unregister_newcredwnd_class(void)
\r
1938 UnregisterClass((LPWSTR) khui_newcredwnd_cls, khm_hInstance);
\r
1941 HWND khm_create_newcredwnd(HWND parent, khui_new_creds * c)
\r
1943 wchar_t wtitle[256];
\r
1946 if (c->window_title == NULL) {
\r
1947 if (c->subtype == KMSG_CRED_PASSWORD)
\r
1948 LoadString(khm_hInstance,
\r
1951 ARRAYLENGTH(wtitle));
\r
1953 LoadString(khm_hInstance,
\r
1956 ARRAYLENGTH(wtitle));
\r
1959 hwnd = CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_CONTEXTHELP,
\r
1960 MAKEINTATOM(khui_newcredwnd_cls),
\r
1961 ((c->window_title)?c->window_title: wtitle),
\r
1962 WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN,
\r
1963 0,0,400,400, /* bogus values. the window
\r
1964 is going to resize and
\r
1973 assert(hwnd != NULL);
\r
1976 /* note that the window is not visible yet. That's because, at
\r
1977 this point we don't know what the panels are */
\r
1982 void khm_prep_newcredwnd(HWND hwnd)
\r
1984 SendMessage(hwnd, KHUI_WM_NC_NOTIFY,
\r
1985 MAKEWPARAM(0, WMNC_DIALOG_SETUP), 0);
\r
1988 void khm_show_newcredwnd(HWND hwnd)
\r
1990 /* add all the panels in and prep UI */
\r
1991 SendMessage(hwnd, KHUI_WM_NC_NOTIFY,
\r
1992 MAKEWPARAM(0, WMNC_DIALOG_ACTIVATE), 0);
\r