oleaut32: Use implementation pointer to avoid casts.
[wine] / dlls / inetcpl.cpl / general.c
1 /*
2  * Internet control panel applet: general propsheet
3  *
4  * Copyright 2010 Detlef Riekenberg
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21
22 #define NONAMELESSUNION
23
24 #include <stdarg.h>
25 #include <windef.h>
26 #include <winbase.h>
27 #include <winuser.h>
28 #include <wininet.h>
29 #include <winreg.h>
30 #include <shlwapi.h>
31 #include <prsht.h>
32
33 #include "inetcpl.h"
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(inetcpl);
37
38 static const WCHAR about_blank[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
39 static const WCHAR start_page[] = {'S','t','a','r','t',' ','P','a','g','e',0};
40 static const WCHAR reg_ie_main[] = {'S','o','f','t','w','a','r','e','\\',
41                                     'M','i','c','r','o','s','o','f','t','\\',
42                                     'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
43                                     'M','a','i','n',0};
44
45 /* list of unimplemented buttons */
46 static DWORD disable_me[] = {IDC_HOME_CURRENT,
47                              IDC_HOME_DEFAULT, 0};
48
49 /*********************************************************************
50  * parse_url_from_outside [internal]
51  *
52  * Filter an URL, add a usable scheme, when needed
53  *
54  */
55 static DWORD parse_url_from_outside(LPCWSTR url, LPWSTR out, DWORD maxlen)
56 {
57     HMODULE hdll;
58     DWORD (WINAPI *pParseURLFromOutsideSourceW)(LPCWSTR, LPWSTR, LPDWORD, LPDWORD);
59     DWORD res;
60
61     hdll = LoadLibraryA("shdocvw.dll");
62     pParseURLFromOutsideSourceW = (void *) GetProcAddress(hdll, (LPSTR) 170);
63
64     if (pParseURLFromOutsideSourceW)
65     {
66         res = pParseURLFromOutsideSourceW(url, out, &maxlen, NULL);
67         FreeLibrary(hdll);
68         return res;
69     }
70
71     ERR("failed to get ordinal 170: %d\n", GetLastError());
72     FreeLibrary(hdll);
73     return 0;
74 }
75
76 /*********************************************************************
77  * general_on_command [internal]
78  *
79  * handle WM_COMMAND
80  *
81  */
82 static INT_PTR general_on_command(HWND hwnd, WPARAM wparam)
83 {
84
85     switch (wparam)
86     {
87         case MAKEWPARAM(IDC_HOME_EDIT, EN_CHANGE):
88             /* enable apply button */
89             SendMessageW(GetParent(hwnd), PSM_CHANGED, (WPARAM)hwnd, 0);
90             break;
91
92         case MAKEWPARAM(IDC_HOME_BLANK, BN_CLICKED):
93             SetDlgItemTextW(hwnd, IDC_HOME_EDIT, about_blank);
94             break;
95
96         default:
97             TRACE("not implemented for command: %d/%d\n", HIWORD(wparam),  LOWORD(wparam));
98             return FALSE;
99     }
100     return TRUE;
101 }
102
103 /*********************************************************************
104  * general_on_initdialog [internal]
105  *
106  * handle WM_INITDIALOG
107  *
108  */
109 static VOID general_on_initdialog(HWND hwnd)
110 {
111     WCHAR buffer[INTERNET_MAX_URL_LENGTH];
112     DWORD len;
113     DWORD type;
114     LONG res;
115     DWORD *ptr = disable_me;
116
117     /* disable unimplemented buttons */
118     while (*ptr)
119     {
120         EnableWindow(GetDlgItem(hwnd, *ptr), FALSE);
121         ptr++;
122     }
123
124     /* read current homepage from the registry. Try HCU first, then HKLM */
125     *buffer = 0;
126     len = sizeof(buffer);
127     type = REG_SZ;
128     res = SHRegGetUSValueW(reg_ie_main, start_page, &type, buffer, &len, FALSE, (LPBYTE) about_blank, sizeof(about_blank));
129
130     if (!res && (type == REG_SZ))
131     {
132         SetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer);
133     }
134 }
135
136 /*********************************************************************
137  * general_on_notify [internal]
138  *
139  * handle WM_NOTIFY
140  *
141  */
142 static INT_PTR general_on_notify(HWND hwnd, WPARAM wparam, LPARAM lparam)
143 {
144     PSHNOTIFY *psn;
145     WCHAR buffer[INTERNET_MAX_URL_LENGTH];
146     WCHAR parsed[INTERNET_MAX_URL_LENGTH];
147     LONG res;
148
149     psn = (PSHNOTIFY *) lparam;
150     TRACE("WM_NOTIFY (%p, 0x%lx, 0x%lx) from %p with code: %d\n", hwnd, wparam, lparam,
151             psn->hdr.hwndFrom, psn->hdr.code);
152
153     if (psn->hdr.code == PSN_APPLY)
154     {
155         *buffer = 0;
156         GetDlgItemTextW(hwnd, IDC_HOME_EDIT, buffer, sizeof(buffer)/sizeof(WCHAR));
157         TRACE("EDITTEXT has %s\n", debugstr_w(buffer));
158
159         res = parse_url_from_outside(buffer, parsed, sizeof(parsed)/sizeof(WCHAR));
160         TRACE("got %d with %s\n", res, debugstr_w(parsed));
161
162         if (res)
163         {
164             HKEY hkey;
165
166             /* update the dialog, when needed */
167             if (lstrcmpW(buffer, parsed))
168                 SetDlgItemTextW(hwnd, IDC_HOME_EDIT, parsed);
169
170             /* update the registry */
171             res = RegOpenKeyW(HKEY_CURRENT_USER, reg_ie_main, &hkey);
172             if (!res)
173             {
174                 res = RegSetValueExW(hkey, start_page, 0, REG_SZ, (const BYTE *)parsed,
175                                     (lstrlenW(parsed) + 1) * sizeof(WCHAR));
176                 RegCloseKey(hkey);
177                 return !res;
178             }
179         }
180     }
181     return FALSE;
182 }
183
184 /*********************************************************************
185  * general_dlgproc [internal]
186  *
187  */
188 INT_PTR CALLBACK general_dlgproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
189 {
190
191     switch (msg)
192     {
193         case WM_INITDIALOG:
194             general_on_initdialog(hwnd);
195             return TRUE;
196
197         case WM_COMMAND:
198             return general_on_command(hwnd, wparam);
199
200         case WM_NOTIFY:
201             return general_on_notify(hwnd, wparam, lparam);
202
203         default:
204             /* do not flood the log */
205             if ((msg == WM_SETCURSOR) || (msg == WM_NCHITTEST) || (msg == WM_MOUSEMOVE))
206                 return FALSE;
207
208             TRACE("(%p, 0x%08x/%d, 0x%lx, 0x%lx)\n", hwnd, msg, msg, wparam, lparam);
209
210     }
211     return FALSE;
212 }