1 // Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
2 //
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License, version 2.0, as
5 // published by the Free Software Foundation.
6 //
7 // This program is also distributed with certain software (including
8 // but not limited to OpenSSL) that is licensed under separate terms,
9 // as designated in a particular file or component or in included license
10 // documentation. The authors of MySQL hereby grant you an
11 // additional permission to link the program and your derivative works
12 // with the separately licensed software that they have included with
13 // MySQL.
14 //
15 // Without limiting anything contained in the foregoing, this file,
16 // which is part of MySQL Connector/ODBC, is also subject to the
17 // Universal FOSS Exception, version 1.0, a copy of which can be found at
18 // http://oss.oracle.com/licenses/universal-foss-exception.
19 //
20 // This program is distributed in the hope that it will be useful, but
21 // WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 // See the GNU General Public License, version 2.0, for more details.
24 //
25 // You should have received a copy of the GNU General Public License
26 // along with this program; if not, write to the Free Software Foundation, Inc.,
27 // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28
29 /**
30 @file odbcdialogparams.cpp
31 @brief Defines the entry point for the DLL application.
32 */
33
34 #define WIN32_LEAN_AND_MEAN
35
36 #include <windows.h>
37 #include <windowsx.h>
38 #include <commctrl.h>
39 #include <stdio.h>
40 #include "resource.h"
41 #include "TabCtrl.h"
42 #include <assert.h>
43 #include <commdlg.h>
44 #include <shlobj.h>
45 #include <xstring>
46 #include <shellapi.h>
47 #include <winsock2.h>
48
49 #include "../setupgui.h"
50
51 #include "odbcdialogparams.h"
52
53 #include "stringutil.h"
54
55 extern HINSTANCE ghInstance;
56
57 static DataSource* pParams= NULL;
58 static PWCHAR pCaption= NULL;
59 static int OkPressed= 0;
60
61 static int mod= 1;
62 static bool flag= false;
63 static bool BusyIndicator= false;
64
65 static TABCTRL TabCtrl_1;
66 /* Whether we are in SQLDriverConnect() prompt mode (used to disable fields) */
67 static BOOL g_isPrompt;
68 /* Variable to keep IDC of control where default value were put. It's reset if
69 user changes value. Used to verify if we can reset that control's value.
70 It won't work if for more than 1 field, but we have only one in visible future. */
71 static long controlWithDefValue= 0;
72
73 HelpButtonPressedCallbackType* gHelpButtonPressedCallback = NULL;
74
75
76 /* Function that enables/disables groups of controls */
77 #define SWITCHED_GROUPS 2
78 #define MAX_GROUP_COTROLS 2
SwitchTcpOrPipe(HWND hwnd,BOOL usePipe)79 void SwitchTcpOrPipe(HWND hwnd, BOOL usePipe)
80 {
81 /* groups of fields to enable/disable*/
82 const int switchedFields[SWITCHED_GROUPS][MAX_GROUP_COTROLS]=
83 {{IDC_EDIT_server, IDC_EDIT_port},
84 {IDC_EDIT_socket, 0}};
85
86 /* Default value for enabled empty field */
87 const LPCWSTR defaultValues[SWITCHED_GROUPS][MAX_GROUP_COTROLS]=
88 {{NULL, NULL}, {L"MySQL", NULL}};
89 /* Can't be sure that usePipe contains 1 as TRUE*/
90 long activeIndex= usePipe ? 1L : 0L;
91
92 for (long i= 0; i < SWITCHED_GROUPS; ++i)
93 for (long j= 0; j < MAX_GROUP_COTROLS && switchedFields[i][j] != 0; ++j)
94 {
95 HWND control= GetDlgItem(hwnd, switchedFields[i][j]);
96 EnableWindow(control, i == activeIndex);
97
98 if (defaultValues[i][j] != NULL)
99 {
100 if (i == activeIndex)
101 {
102 if (Edit_GetTextLength(control) == 0)
103 {
104 /* remember that we set that value */
105 Edit_SetText(control, defaultValues[i][j]);
106 controlWithDefValue= switchedFields[i][j];
107 }
108 }
109 else if (controlWithDefValue == switchedFields[i][j])
110 {
111 /* we don't want to store the value we set instead of user */
112 Edit_SetText(control,L"");
113 }
114 }
115 }
116 }
117 #undef SWITCHED_GROUPS
118 #undef MAX_GROUP_COTROLS
119
120
InitStaticValues()121 void InitStaticValues()
122 {
123 BusyIndicator= true;
124 pParams = NULL;
125 pCaption = NULL;
126 OkPressed = 0;
127
128 mod = 1;
129 flag = false;
130 BusyIndicator= false;
131
132 gHelpButtonPressedCallback= NULL;
133 }
134
135
136 #define Refresh(A) RedrawWindow(A,NULL,NULL,RDW_ERASE|RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_UPDATENOW);
137
138 BOOL FormMain_DlgProc (HWND, UINT, WPARAM, LPARAM);
139
140
DoEvents(void)141 void DoEvents (void)
142 {
143 MSG Msg;
144 while (PeekMessage(&Msg,NULL,0,0,PM_REMOVE))
145 {
146 TranslateMessage(&Msg);
147 DispatchMessage(&Msg);
148 }
149 }
150
151
152 VOID OnWMNotify(WPARAM wParam, LPARAM lParam);
153
154
FormMain_OnNotify(HWND hwnd,WPARAM wParam,LPARAM lParam)155 static BOOL FormMain_OnNotify (HWND hwnd, WPARAM wParam, LPARAM lParam)
156 {
157 OnWMNotify(wParam, lParam);
158 int id = (int)wParam;
159
160 switch(id)
161 {
162 case IDC_TAB1:
163 {
164 TabControl_Select(&TabCtrl_1); //update internal "this" pointer
165
166 LPNMHDR nm = (LPNMHDR)lParam;
167 switch (nm->code)
168 {
169 case TCN_KEYDOWN:
170 TabCtrl_1.OnKeyDown(lParam);
171
172 case TCN_SELCHANGE:
173 TabCtrl_1.OnSelChanged();
174 }
175 }
176 break;
177 }
178
179 return FALSE;
180 }
181
182
getStrFieldData(HWND hwnd,SQLWCHAR ** param,int idc)183 void getStrFieldData(HWND hwnd, SQLWCHAR **param, int idc)
184 {
185 x_free(*param);
186 *param= NULL;
187
188 int len = Edit_GetTextLength(GetDlgItem(hwnd,idc));
189
190 if (len>0)
191 {
192 *param= (SQLWCHAR *)myodbc_malloc((len + 1) * sizeof(SQLWCHAR), MYF(0));
193 if (*param)
194 Edit_GetText(GetDlgItem(hwnd,idc), *param, len+1);
195 }
196 }
197
198
getStrFieldDataTab(SQLWCHAR ** param,unsigned int framenum,int idc)199 void getStrFieldDataTab(SQLWCHAR **param, unsigned int framenum, int idc)
200 {
201 assert(TabCtrl_1.hTabPages);
202 HWND tab = TabCtrl_1.hTabPages[framenum-1];
203
204 assert(tab);
205
206 getStrFieldData(tab, param, idc);
207 }
208
setComboFieldDataTab(SQLWCHAR * param,unsigned int framenum,int idc)209 void setComboFieldDataTab(SQLWCHAR *param, unsigned int framenum, int idc)
210 {
211 if ( TabCtrl_1.hTabPages[framenum-1])
212 {
213 HWND tabHwndMisc = TabCtrl_1.hTabPages[framenum-1];
214 HWND charsetCtrl = GetDlgItem(tabHwndMisc, idc);
215 ComboBox_SetText(charsetCtrl, param);
216 }
217 }
218
219
setStrFieldData(HWND hwnd,SQLWCHAR * param,int idc)220 void setStrFieldData(HWND hwnd, SQLWCHAR *param, int idc)
221 {
222 Edit_SetText(GetDlgItem(hwnd, idc), param);
223 }
224
225
setStrFieldDataTab(SQLWCHAR * param,unsigned int framenum,int idc)226 void setStrFieldDataTab(SQLWCHAR *param, unsigned int framenum, int idc)
227 {
228 assert(TabCtrl_1.hTabPages);
229 HWND tab = TabCtrl_1.hTabPages[framenum-1];
230
231 assert(tab);
232
233 setStrFieldData(tab, param, idc);
234 }
235
236
getUnsignedFieldDataTab(unsigned int framenum,unsigned int * param,int idc)237 void getUnsignedFieldDataTab(unsigned int framenum, unsigned int *param, int idc )
238 {
239 getUnsignedFieldData(TabCtrl_1.hTabPages[framenum-1], param, idc);
240 }
241
242
getUnsignedFieldData(HWND hwnd,unsigned int * param,int idc)243 void getUnsignedFieldData(HWND hwnd, unsigned int *param, int idc)
244 {
245 *param = 0U;
246 int len = Edit_GetTextLength(GetDlgItem(hwnd,idc));
247
248 if(len>0)
249 {
250 SQLWCHAR *tmp1= (SQLWCHAR *)myodbc_malloc((len + 1) * sizeof(SQLWCHAR),
251 MYF(0));
252 if (tmp1)
253 {
254 Edit_GetText(GetDlgItem(hwnd,idc), tmp1, len+1);
255 *param = _wtol(tmp1);
256 x_free(tmp1);
257 }
258 }
259 }
260
261
setUnsignedFieldData(HWND hwnd,const unsigned int param,int idc)262 void setUnsignedFieldData(HWND hwnd, const unsigned int param, int idc)
263 {
264 wchar_t buf[20];
265 _itow( param, (wchar_t*)buf, 10 );
266 Edit_SetText(GetDlgItem(hwnd,idc), buf);
267 }
268
269
setUnsignedFieldDataTab(unsigned int framenum,const unsigned int param,int idc)270 void setUnsignedFieldDataTab(unsigned int framenum, const unsigned int param, int idc)
271 {
272 setUnsignedFieldData(TabCtrl_1.hTabPages[framenum-1], param, idc);
273 }
274
275
getTabCtrlTab(void)276 HWND getTabCtrlTab(void)
277 {
278 return TabCtrl_1.hTab;
279 }
280
281
getTabCtrlTabPages(unsigned int framenum)282 HWND getTabCtrlTabPages(unsigned int framenum)
283 {
284 return TabCtrl_1.hTabPages[framenum];
285 }
286
287
getBoolFieldDataTab(unsigned int framenum,int idc)288 my_bool getBoolFieldDataTab(unsigned int framenum, int idc)
289 {
290 assert(TabCtrl_1.hTabPages);
291 HWND checkbox = GetDlgItem(TabCtrl_1.hTabPages[framenum-1], idc);
292
293 assert(checkbox);
294 if (checkbox)
295 return !!Button_GetCheck(checkbox);
296
297 return false;
298 }
299
300
301 /* this reads non-DSN bool data */
getBoolFieldData(HWND hwnd,int idc)302 my_bool getBoolFieldData(HWND hwnd, int idc)
303 {
304 HWND checkbox = GetDlgItem(hwnd, idc);
305
306 assert(checkbox);
307 if (checkbox)
308 return !!Button_GetCheck(checkbox);
309
310 return false;
311 }
312
313
setBoolFieldData(HWND hwnd,int idc,my_bool state)314 void setBoolFieldData(HWND hwnd, int idc, my_bool state)
315 {
316 HWND checkbox = GetDlgItem(hwnd, idc);
317 assert(checkbox);
318 if (checkbox)
319 Button_SetCheck(checkbox, state);
320 }
321
322
setBoolFieldDataTab(unsigned int framenum,int idc,my_bool state)323 void setBoolFieldDataTab(unsigned int framenum, int idc, my_bool state)
324 {
325 assert(TabCtrl_1.hTabPages);
326 Button_SetCheck(GetDlgItem(TabCtrl_1.hTabPages[framenum-1],idc), state);
327
328 }
329
330
setControlEnabled(unsigned int framenum,int idc,my_bool state)331 void setControlEnabled(unsigned int framenum, int idc, my_bool state)
332 {
333 HWND cursorTab= TabCtrl_1.hTabPages[framenum-1];
334 assert(cursorTab);
335
336 if (cursorTab)
337 {
338 EnableWindow(GetDlgItem(cursorTab, idc), state);
339 }
340 }
341
342
343 void OnDialogClose();
344
345
FormMain_OnClose(HWND hwnd)346 void FormMain_OnClose(HWND hwnd)
347 {
348 //PostQuitMessage(0);// turn off message loop
349 //Unhooks hook(s) :)
350 OnDialogClose();
351
352 TabControl_Destroy(&TabCtrl_1);
353 EndDialog(hwnd, NULL);
354 }
355
356
357 /****************************************************************************
358 * *
359 * Functions: FormMain_OnCommand related event code *
360 * *
361 * Purpose : Handle WM_COMMAND messages: this is the heart of the app. *
362 * *
363 * History : Date Reason *
364 * 00/00/00 Created *
365 * *
366 ****************************************************************************/
btnDetails_Click(HWND hwnd)367 void btnDetails_Click (HWND hwnd)
368 {
369 RECT rect;
370 GetWindowRect( hwnd, &rect );
371 mod *= -1;
372 ShowWindow( GetDlgItem(hwnd,IDC_TAB1), mod > 0? SW_SHOW: SW_HIDE );
373
374 if(!flag && mod==1)
375 {
376 static PWSTR tabnames[]= {L"Connection", L"Metadata", L"Cursors/Results", L"Debug", L"SSL", L"Misc", 0};
377 static PWSTR dlgnames[]= {MAKEINTRESOURCE(IDD_TAB1),
378 MAKEINTRESOURCE(IDD_TAB2),
379 MAKEINTRESOURCE(IDD_TAB3),
380 MAKEINTRESOURCE(IDD_TAB4),
381 MAKEINTRESOURCE(IDD_TAB5),
382 MAKEINTRESOURCE(IDD_TAB6),0};
383
384 New_TabControl( &TabCtrl_1, // address of TabControl struct
385 GetDlgItem(hwnd, IDC_TAB1), // handle to tab control
386 tabnames, // text for each tab
387 dlgnames, // dialog id's of each tab page dialog
388 &FormMain_DlgProc, // address of main windows proc
389 NULL, // address of size function
390 TRUE); // stretch tab page to fit tab ctrl
391 flag = true;
392
393
394 HWND ssl_tab = TabCtrl_1.hTabPages[4];
395 HWND combo = GetDlgItem(ssl_tab, IDC_EDIT_sslmode);
396
397 ComboBox_ResetContent(combo);
398
399 ComboBox_AddString(combo, L"");
400 ComboBox_AddString(combo, LSTR(ODBC_SSL_MODE_DISABLED));
401 ComboBox_AddString(combo, LSTR(ODBC_SSL_MODE_PREFERRED));
402 ComboBox_AddString(combo, LSTR(ODBC_SSL_MODE_REQUIRED));
403 ComboBox_AddString(combo, LSTR(ODBC_SSL_MODE_VERIFY_CA));
404 ComboBox_AddString(combo, LSTR(ODBC_SSL_MODE_VERIFY_IDENTITY));
405
406 syncTabs(hwnd, pParams);
407 }
408 MoveWindow( hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top + 310*mod, TRUE );
409 }
410
411
btnOk_Click(HWND hwnd)412 void btnOk_Click (HWND hwnd)
413 {
414 FillParameters(hwnd, pParams);
415
416 /* if DS params are valid, close dialog */
417 if (mytestaccept(hwnd, pParams))
418 {
419 OkPressed= 1;
420 PostMessage(hwnd, WM_CLOSE, NULL, NULL);
421 }
422 }
423
424
btnCancel_Click(HWND hwnd)425 void btnCancel_Click (HWND hwnd)
426 {
427 PostMessage(hwnd, WM_CLOSE, NULL, NULL);
428 }
429
430
btnTest_Click(HWND hwnd)431 void btnTest_Click (HWND hwnd)
432 {
433 FillParameters(hwnd, pParams);
434 wchar_t *testResultMsg= mytest(hwnd, pParams);
435 MessageBoxW(hwnd, testResultMsg, L"Test Result", MB_OK);
436 x_free(testResultMsg);
437 }
438
439
btnHelp_Click(HWND hwnd)440 void btnHelp_Click (HWND hwnd)
441 {
442 ShellExecute(NULL, L"open",
443 L"http://dev.mysql.com/doc/refman/5.1/en/connector-odbc-configuration-dsn-windows.html",
444 NULL, NULL, SW_SHOWNORMAL);
445 }
446
447
chooseFile(HWND parent,int hostCtlId)448 void chooseFile( HWND parent, int hostCtlId )
449 {
450 OPENFILENAMEW dialog;
451
452 HWND hostControl = GetDlgItem( parent, hostCtlId );
453
454 wchar_t szFile[MAX_PATH]; // buffer for file name
455
456 Edit_GetText( hostControl, szFile, sizeof(szFile) );
457 // Initialize OPENFILENAME
458 ZeroMemory(&dialog, sizeof(dialog));
459
460 dialog.lStructSize = sizeof(dialog);
461 dialog.lpstrFile = szFile;
462
463 dialog.lpstrTitle = L"Select File";
464 dialog.nMaxFile = sizeof(szFile);
465 dialog.lpstrFileTitle = NULL;
466 dialog.nMaxFileTitle = 0;
467 dialog.lpstrInitialDir = NULL;
468 dialog.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST ;
469 dialog.hwndOwner = parent;
470 dialog.lpstrCustomFilter = L"All Files\0*.*\0PEM\0*.pem\0";
471 dialog.nFilterIndex = 2;
472
473 if ( GetOpenFileNameW( &dialog ) )
474 {
475 Edit_SetText( hostControl, dialog.lpstrFile );
476 }
477 }
478
479
choosePath(HWND parent,int hostCtlId)480 void choosePath( HWND parent, int hostCtlId )
481 {
482 HWND hostControl = GetDlgItem( parent, hostCtlId );
483
484 BROWSEINFOW dialog;
485 wchar_t path[MAX_PATH]; // buffer for file name
486
487 Edit_GetText( hostControl, path, sizeof(path) );
488
489 ZeroMemory(&dialog,sizeof(dialog));
490
491 dialog.lpszTitle = L"Pick a CA Path";
492 dialog.hwndOwner = parent;
493 dialog.pszDisplayName = path;
494
495 LPITEMIDLIST pidl = SHBrowseForFolder ( &dialog );
496
497 if ( pidl )
498 {
499 SHGetPathFromIDList ( pidl, path );
500
501 Edit_SetText( hostControl, path );
502
503 IMalloc * imalloc = 0;
504 if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
505 {
506 imalloc->Free ( pidl );
507 imalloc->Release ( );
508 }
509 }
510 }
511
512 #ifndef MAX_VISIBLE_CB_ITEMS
513 #define MAX_VISIBLE_CB_ITEMS 20
514 #endif
515
516
517 /**
518 Adjusting height of dropped list of cbHwnd combobox to fit
519 itemsCount items, but not more than MAX_VISIBLE_CB_ITEMS
520 ComboBox_SetMinVisible not used because it was introduced in XP.
521 */
adjustDropdownHeight(HWND cbHwnd,unsigned int itemsCount)522 int adjustDropdownHeight(HWND cbHwnd, unsigned int itemsCount)
523 {
524 COMBOBOXINFO dbcbinfo;
525 RECT ddRect;
526 int newHeight = 0;
527
528 dbcbinfo.cbSize= sizeof(COMBOBOXINFO);
529 ComboBox_GetDroppedControlRect(cbHwnd, &ddRect);
530 newHeight= ddRect.bottom - ddRect.top;
531
532 if ( GetComboBoxInfo(cbHwnd, &dbcbinfo) )
533 {
534 itemsCount= itemsCount < 1 ? 1 : (itemsCount > MAX_VISIBLE_CB_ITEMS
535 ? MAX_VISIBLE_CB_ITEMS
536 : itemsCount );
537
538 /* + (itemsCount - 1) - 1 pixel spaces between list items */
539 newHeight= itemsCount*ComboBox_GetItemHeight(cbHwnd) + (itemsCount - 1);
540 MoveWindow(dbcbinfo.hwndList, ddRect.left, ddRect.top, ddRect.right-ddRect.left, newHeight, FALSE);
541 }
542
543 return newHeight;
544 }
545
546
547 /**
548 Processing commands for dbname combobox (hwndCtl).
549 */
processDbCombobox(HWND hwnd,HWND hwndCtl,UINT codeNotify)550 void processDbCombobox(HWND hwnd, HWND hwndCtl, UINT codeNotify)
551 {
552 switch(codeNotify)
553 {
554 /* Loading list and adjust its height if button clicked and on user input */
555 case(CBN_DROPDOWN):
556 {
557 FillParameters(hwnd, pParams);
558 LIST *dbs= mygetdatabases(hwnd, pParams);
559 LIST *dbtmp= dbs;
560
561 ComboBox_ResetContent(hwndCtl);
562
563 adjustDropdownHeight(hwndCtl,list_length(dbs));
564
565 for (; dbtmp; dbtmp= list_rest(dbtmp))
566 ComboBox_AddString(hwndCtl, (SQLWCHAR *)dbtmp->data);
567
568 list_free(dbs, 1);
569
570 ComboBox_SetText(hwndCtl,pParams->database);
571
572 break;
573 }
574 }
575 }
576
577
578 /**
579 Processing commands for charset combobox (hwndCtl).
580 */
processCharsetCombobox(HWND hwnd,HWND hwndCtl,UINT codeNotify)581 void processCharsetCombobox(HWND hwnd, HWND hwndCtl, UINT codeNotify)
582 {
583 switch(codeNotify)
584 {
585 /* Loading list and adjust its height if button clicked and on user input */
586 case(CBN_DROPDOWN):
587 {
588 //FillParameters(hwnd, *pParams);
589 LIST *csl= mygetcharsets(hwnd, pParams);
590 LIST *cstmp= csl;
591
592 ComboBox_ResetContent(hwndCtl);
593
594 adjustDropdownHeight(hwndCtl,list_length(csl));
595
596 for (; cstmp; cstmp= list_rest(cstmp))
597 ComboBox_AddString(hwndCtl, (SQLWCHAR *)cstmp->data);
598
599 list_free(csl, 1);
600
601 ComboBox_SetText(hwndCtl,pParams->charset);
602
603 break;
604 }
605 }
606 }
607
608
FormMain_OnCommand(HWND hwnd,int id,HWND hwndCtl,UINT codeNotify)609 void FormMain_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
610 {
611 if (controlWithDefValue != 0 && id == controlWithDefValue
612 && codeNotify==EN_CHANGE)
613 controlWithDefValue= 0;
614
615 switch (id)
616 {
617 case IDOK:
618 btnOk_Click(hwnd); break;
619 case IDCANCEL:
620 btnCancel_Click(hwnd); break;
621 case IDC_BUTTON_DETAILS:
622 btnDetails_Click(hwnd); break;
623 case IDC_BUTTON_HELP:
624 btnHelp_Click(hwnd); break;
625 case IDC_BUTTON_TEST:
626 btnTest_Click(hwnd); break;
627 case IDC_SSLKEYCHOOSER:
628 chooseFile(hwnd, IDC_EDIT_sslkey); break;
629 case IDC_SSLCERTCHOOSER:
630 chooseFile(hwnd, IDC_EDIT_sslcert); break;
631 case IDC_SSLCACHOOSER:
632 chooseFile(hwnd, IDC_EDIT_sslca); break;
633 case IDC_SSLCAPATHCHOOSER:
634 choosePath(hwnd, IDC_EDIT_sslcapath); break;
635 case IDC_RSAKEYCHOOSER:
636 chooseFile(hwnd, IDC_EDIT_rsakey); break;
637 case IDC_CHOOSER_plugin_dir:
638 choosePath(hwnd, IDC_EDIT_plugin_dir); break;
639 case IDC_RADIO_tcp:
640 case IDC_RADIO_pipe:
641 SwitchTcpOrPipe(hwnd, !!Button_GetCheck(GetDlgItem(hwnd, IDC_RADIO_pipe)));
642 break;
643 case IDC_CHECK_cursor_prefetch_active:
644 {
645 HWND cursorTab= TabCtrl_1.hTabPages[CURSORS_TAB-1];
646 assert(cursorTab);
647 HWND prefetch= GetDlgItem(cursorTab, IDC_EDIT_cursor_prefetch_number);
648 assert(prefetch);
649
650 EnableWindow(prefetch, !!Button_GetCheck(GetDlgItem(cursorTab,
651 IDC_CHECK_cursor_prefetch_active)));
652
653 if (Edit_GetTextLength(prefetch) == 0)
654 {
655 setUnsignedFieldData(cursorTab, default_cursor_prefetch,
656 IDC_EDIT_cursor_prefetch_number);
657 }
658 }
659 break;
660 case IDC_EDIT_name:
661 {
662 if (codeNotify==EN_CHANGE)
663 {
664 int len = Edit_GetTextLength(GetDlgItem(hwnd,IDC_EDIT_name));
665 Button_Enable(GetDlgItem(hwnd,IDOK), len > 0);
666 Button_Enable(GetDlgItem(hwnd,IDC_BUTTON_TEST), len > 0);
667 RedrawWindow(hwnd,NULL,NULL,RDW_INVALIDATE);
668 }
669 break;
670 }
671
672 case IDC_EDIT_dbname:
673 processDbCombobox(hwnd, hwndCtl, codeNotify);
674 break;
675
676 case IDC_EDIT_charset:
677 processCharsetCombobox(hwnd, hwndCtl, codeNotify);
678 }
679
680 return;
681 }
682
683
684 void AlignWindowToBottom(HWND hwnd, int dY);
685 void AdjustLayout(HWND hwnd);
686
687
FormMain_OnSize(HWND hwnd,UINT state,int cx,int cy)688 void FormMain_OnSize(HWND hwnd, UINT state, int cx, int cy)
689 {
690 AdjustLayout(hwnd);
691 }
692
693 static int yCurrentScroll = 0; // current vertical scroll value
694
FormMain_OnScroll(HWND hwnd,HWND hCtrl,UINT code,int pos)695 void FormMain_OnScroll(HWND hwnd, HWND hCtrl, UINT code, int pos)
696 {
697 SCROLLINFO si;
698 si.cbSize = sizeof(si);
699 si.fMask = SIF_POS;
700 int yNewPos; // new position
701 switch (code)
702 {
703 // User clicked the scroll bar shaft above the scroll box.
704 case SB_PAGEUP:
705 yNewPos = yCurrentScroll - 50;
706 break;
707
708 // User clicked the scroll bar shaft below the scroll box.
709 case SB_PAGEDOWN:
710 yNewPos = yCurrentScroll + 50;
711 break;
712
713 // User clicked the top arrow.
714 case SB_LINEUP:
715 yNewPos = yCurrentScroll - 5;
716 break;
717
718 // User clicked the bottom arrow.
719 case SB_LINEDOWN:
720 yNewPos = yCurrentScroll + 5;
721 break;
722
723 // User dragged the scroll box.
724 case SB_THUMBPOSITION:
725 yNewPos = pos;
726 break;
727
728 default:
729 yNewPos = yCurrentScroll;
730 }
731
732 si.nPos = yNewPos;
733
734 ScrollWindowEx(hwnd, 0, -50,
735 NULL, NULL, NULL, NULL, SW_INVALIDATE);
736 UpdateWindow(hwnd);
737
738 SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
739 yCurrentScroll = yNewPos;
740 }
741
AdjustLayout(HWND hwnd)742 void AdjustLayout(HWND hwnd)
743 {
744 RECT rc;
745 GetClientRect(hwnd,&rc);
746
747 BOOL Visible = (mod==-1)?0:1;
748
749 if(TabCtrl_1.hTab)
750 {
751 EnableWindow( TabCtrl_1.hTab, Visible );
752 ShowWindow( TabCtrl_1.hTab, Visible );
753 }
754
755 PWSTR pButtonCaption = Visible? L"Details <<" : L"Details >>";
756 SetWindowText( GetDlgItem(hwnd,IDC_BUTTON_DETAILS), pButtonCaption );
757 const int dY = 20;
758 AlignWindowToBottom( GetDlgItem(hwnd,IDC_BUTTON_DETAILS), dY);
759 AlignWindowToBottom( GetDlgItem(hwnd,IDOK), dY);
760 AlignWindowToBottom( GetDlgItem(hwnd,IDCANCEL), dY);
761 AlignWindowToBottom( GetDlgItem(hwnd,IDC_BUTTON_HELP), dY);
762
763 Refresh(hwnd);
764 }
765
766
AlignWindowToBottom(HWND hwnd,int dY)767 void AlignWindowToBottom(HWND hwnd, int dY)
768 {
769 if(!hwnd)
770 return;
771 RECT rect;
772 GetWindowRect( hwnd, &rect );
773 int h, w;
774 RECT rc;
775 GetWindowRect(GetParent(hwnd), &rc);
776
777 h=rect.bottom-rect.top;
778 w=rect.right-rect.left;
779
780 rc.top = rc.bottom;
781 MapWindowPoints(HWND_DESKTOP, GetParent(hwnd), (LPPOINT)&rect, 2);
782 MapWindowPoints(HWND_DESKTOP, GetParent(hwnd), (LPPOINT)&rc, 2);
783
784 MoveWindow(hwnd, rect.left, rc.top -dY-h,w,h,FALSE);
785 }
786
787
788 HWND g_hwndDlg;
789 BOOL DoCreateDialogTooltip(void);
790
791
FormMain_OnInitDialog(HWND hwnd,HWND hwndFocus,LPARAM lParam)792 BOOL FormMain_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
793 {
794 g_hwndDlg = hwnd;
795 SetWindowText(hwnd, pCaption);
796 //----Everything else must follow the above----//
797 btnDetails_Click(hwnd);
798 AdjustLayout(hwnd);
799 //Get the initial Width and height of the dialog
800 //in order to fix the minimum size of dialog
801
802 syncForm(hwnd, pParams);
803
804 /* Disable fields if in prompt mode */
805 if (g_isPrompt)
806 {
807 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_name), FALSE);
808 EnableWindow(GetDlgItem(hwnd, IDC_EDIT_description), FALSE);
809 }
810
811 /* if prompting without DSN, don't disable OK button */
812 /* preserved here old logic + enabled OK if data source
813 name is not NULL when not prompting. I don't know why it should be disabled
814 when prompting and name is not NULL. */
815 if (g_isPrompt == (pParams->name==NULL))
816 {
817 Button_Enable(GetDlgItem(hwnd,IDOK), 1);
818 Button_Enable(GetDlgItem(hwnd,IDC_BUTTON_TEST), 1);
819 RedrawWindow(hwnd,NULL,NULL,RDW_INVALIDATE);
820 }
821
822 BOOL b = DoCreateDialogTooltip();
823 return 0;
824 }
825
826
FormMain_DlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)827 BOOL FormMain_DlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
828 {
829 switch(msg)
830 {
831 HANDLE_MSG (hwndDlg, WM_CLOSE, FormMain_OnClose);
832 HANDLE_MSG (hwndDlg, WM_COMMAND, FormMain_OnCommand);
833 HANDLE_MSG (hwndDlg, WM_INITDIALOG, FormMain_OnInitDialog);
834 HANDLE_MSG (hwndDlg, WM_SIZE, FormMain_OnSize);
835 HANDLE_MSG (hwndDlg, WM_VSCROLL, FormMain_OnScroll);
836 // There is no message cracker for WM_NOTIFY so redirect manually
837 case WM_NOTIFY:
838 return FormMain_OnNotify (hwndDlg,wParam,lParam);
839
840 default: return FALSE;
841 }
842 }
843
844
845 /*
846 Display the DSN dialog
847
848 @param params DataSource struct, should be pre-populated
849 @param ParentWnd Parent window handle
850 @return 1 if the params were correctly populated and OK was pressed
851 0 if the dialog was closed or cancelled
852 */
853 extern "C"
ShowOdbcParamsDialog(DataSource * params,HWND ParentWnd,BOOL isPrompt)854 int ShowOdbcParamsDialog(DataSource* params, HWND ParentWnd, BOOL isPrompt)
855 {
856 assert(!BusyIndicator);
857 InitStaticValues();
858
859 pParams= params;
860 pCaption= L"MySQL Connector/ODBC Data Source Configuration";
861 g_isPrompt= isPrompt;
862
863 /*
864 If prompting (with a DSN name), or not prompting (add/edit DSN),
865 we translate the lib path to the actual driver name.
866 */
867 if (params->name || !isPrompt)
868 {
869 Driver *driver= driver_new();
870 params->driver && memcpy(driver->lib, params->driver,
871 (sqlwcharlen(params->driver) + 1) * sizeof(SQLWCHAR));
872 /* TODO Driver lookup is done in driver too, do we really need it there? */
873 if (!*driver->lib || driver_lookup_name(driver))
874 {
875 wchar_t msg[256];
876 swprintf(msg, 256, L"Failure to lookup driver entry at path '%ls'",
877 driver->lib);
878 MessageBox(ParentWnd, msg, L"Cannot find driver entry", MB_OK);
879 driver_delete(driver);
880 return 0;
881 }
882 ds_set_strattr(¶ms->driver, driver->name);
883 driver_delete(driver);
884 }
885 DialogBox(ghInstance, MAKEINTRESOURCE(IDD_DIALOG1), ParentWnd,
886 (DLGPROC)FormMain_DlgProc);
887
888 BusyIndicator= false;
889 return OkPressed;
890 }
891