2 * ieframe - Internet Explorer main frame window
4 * Copyright 2006 Mike McCormack (for CodeWeavers)
5 * Copyright 2006 Jacek Caban (for CodeWeavers)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
42 #include "ieautomation.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(ieframe
);
50 #define WM_UPDATEADDRBAR (WM_APP+1)
52 static const WCHAR szIEWinFrame
[] = { 'I','E','F','r','a','m','e',0 };
54 /* Windows uses "Microsoft Internet Explorer" */
55 static const WCHAR wszWineInternetExplorer
[] =
56 {'W','i','n','e',' ','I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0};
59 static DWORD dde_inst
;
60 static HSZ ddestr_iexplore
, ddestr_openurl
;
61 static struct list ie_list
= LIST_INIT(ie_list
);
63 HRESULT
update_ie_statustext(InternetExplorer
* This
, LPCWSTR text
)
65 if(!SendMessageW(This
->status_hwnd
, SB_SETTEXTW
, MAKEWORD(SB_SIMPLEID
, 0), (LPARAM
)text
))
71 static void adjust_ie_docobj_rect(HWND frame
, RECT
* rc
)
73 HWND hwndRebar
= GetDlgItem(frame
, IDC_BROWSE_REBAR
);
74 HWND hwndStatus
= GetDlgItem(frame
, IDC_BROWSE_STATUSBAR
);
75 INT barHeight
= SendMessageW(hwndRebar
, RB_GETBARHEIGHT
, 0, 0);
77 InflateRect(rc
, 0, -barHeight
);
79 if(IsWindowVisible(hwndStatus
))
83 GetClientRect(hwndStatus
, &statusrc
);
84 rc
->bottom
-= statusrc
.bottom
- statusrc
.top
;
88 static HMENU
get_tb_menu(HMENU menu
)
90 HMENU menu_view
= GetSubMenu(menu
, 1);
92 return GetSubMenu(menu_view
, 0);
95 static HMENU
get_fav_menu(HMENU menu
)
97 return GetSubMenu(menu
, 2);
100 static LPWSTR
get_fav_url_from_id(HMENU menu
, UINT id
)
104 item
.cbSize
= sizeof(item
);
105 item
.fMask
= MIIM_DATA
;
107 if(!GetMenuItemInfoW(menu
, id
, FALSE
, &item
))
110 return (LPWSTR
)item
.dwItemData
;
113 static void free_fav_menu_data(HMENU menu
)
118 for(i
= 0; (url
= get_fav_url_from_id(menu
, ID_BROWSE_GOTOFAV_FIRST
+ i
)); i
++)
122 static int get_menu_item_count(HMENU menu
)
128 item
.cbSize
= sizeof(item
);
129 item
.fMask
= MIIM_DATA
| MIIM_SUBMENU
;
131 for(i
= 0; GetMenuItemInfoW(menu
, i
, TRUE
, &item
); i
++)
134 count
+= get_menu_item_count(item
.hSubMenu
);
142 static void add_fav_to_menu(HMENU favmenu
, HMENU menu
, LPWSTR title
, LPCWSTR url
)
145 /* Subtract the number of standard elements in the Favorites menu */
146 int favcount
= get_menu_item_count(favmenu
) - 2;
149 if(favcount
> (ID_BROWSE_GOTOFAV_MAX
- ID_BROWSE_GOTOFAV_FIRST
))
151 FIXME("Add support for more than %d Favorites\n", favcount
);
155 urlbuf
= heap_alloc((lstrlenW(url
) + 1) * sizeof(WCHAR
));
160 lstrcpyW(urlbuf
, url
);
162 item
.cbSize
= sizeof(item
);
163 item
.fMask
= MIIM_FTYPE
| MIIM_STRING
| MIIM_DATA
| MIIM_ID
;
164 item
.fType
= MFT_STRING
;
165 item
.dwTypeData
= title
;
166 item
.wID
= ID_BROWSE_GOTOFAV_FIRST
+ favcount
;
167 item
.dwItemData
= (ULONG_PTR
)urlbuf
;
168 InsertMenuItemW(menu
, -1, TRUE
, &item
);
171 static void add_favs_to_menu(HMENU favmenu
, HMENU menu
, LPCWSTR dir
)
173 WCHAR path
[MAX_PATH
*2];
174 const WCHAR search
[] = {'*',0};
177 WIN32_FIND_DATAW finddata
;
178 IUniformResourceLocatorW
* urlobj
;
179 IPersistFile
* urlfile
= NULL
;
183 PathAppendW(path
, search
);
185 findhandle
= FindFirstFileW(path
, &finddata
);
187 if(findhandle
== INVALID_HANDLE_VALUE
)
190 res
= CoCreateInstance(&CLSID_InternetShortcut
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IUniformResourceLocatorW
, (PVOID
*)&urlobj
);
193 res
= IUnknown_QueryInterface((IUnknown
*)urlobj
, &IID_IPersistFile
, (PVOID
*)&urlfile
);
197 filename
= path
+ lstrlenW(path
) - lstrlenW(search
);
201 lstrcpyW(filename
, finddata
.cFileName
);
203 if(finddata
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
206 const WCHAR ignore1
[] = {'.','.',0};
207 const WCHAR ignore2
[] = {'.',0};
209 if(!lstrcmpW(filename
, ignore1
) || !lstrcmpW(filename
, ignore2
))
212 item
.cbSize
= sizeof(item
);
213 item
.fMask
= MIIM_STRING
| MIIM_SUBMENU
;
214 item
.dwTypeData
= filename
;
215 item
.hSubMenu
= CreatePopupMenu();
216 InsertMenuItemW(menu
, -1, TRUE
, &item
);
217 add_favs_to_menu(favmenu
, item
.hSubMenu
, path
);
222 const WCHAR urlext
[] = {'.','u','r','l',0};
224 if(lstrcmpiW(PathFindExtensionW(filename
), urlext
))
227 if(FAILED(IPersistFile_Load(urlfile
, path
, 0)))
230 urlobj
->lpVtbl
->GetURL(urlobj
, &url
);
235 fileext
= filename
+ lstrlenW(filename
) - lstrlenW(urlext
);
237 add_fav_to_menu(favmenu
, menu
, filename
, url
);
239 } while(FindNextFileW(findhandle
, &finddata
));
243 IPersistFile_Release(urlfile
);
246 IUnknown_Release((IUnknown
*)urlobj
);
248 FindClose(findhandle
);
251 static void add_tbs_to_menu(HMENU menu
)
253 HUSKEY toolbar_handle
;
254 WCHAR toolbar_key
[] = {'S','o','f','t','w','a','r','e','\\',
255 'M','i','c','r','o','s','o','f','t','\\',
256 'I','n','t','e','r','n','e','t',' ',
257 'E','x','p','l','o','r','e','r','\\',
258 'T','o','o','l','b','a','r',0};
260 if(SHRegOpenUSKeyW(toolbar_key
, KEY_READ
, NULL
, &toolbar_handle
, TRUE
) == ERROR_SUCCESS
)
262 HUSKEY classes_handle
;
263 WCHAR classes_key
[] = {'S','o','f','t','w','a','r','e','\\',
264 'C','l','a','s','s','e','s','\\','C','L','S','I','D',0};
266 DWORD value_len
= ARRAY_SIZE(guid
);
269 if(SHRegOpenUSKeyW(classes_key
, KEY_READ
, NULL
, &classes_handle
, TRUE
) != ERROR_SUCCESS
)
271 SHRegCloseUSKey(toolbar_handle
);
272 ERR("Failed to open key %s\n", debugstr_w(classes_key
));
276 for(i
= 0; SHRegEnumUSValueW(toolbar_handle
, i
, guid
, &value_len
, NULL
, NULL
, NULL
, SHREGENUM_HKLM
) == ERROR_SUCCESS
; i
++)
279 DWORD tb_name_len
= ARRAY_SIZE(tb_name
);
280 HUSKEY tb_class_handle
;
283 value_len
= ARRAY_SIZE(guid
);
285 if(lstrlenW(guid
) != 38)
287 TRACE("Found invalid IE toolbar entry: %s\n", debugstr_w(guid
));
291 if(SHRegOpenUSKeyW(guid
, KEY_READ
, classes_handle
, &tb_class_handle
, TRUE
) != ERROR_SUCCESS
)
293 ERR("Failed to get class info for %s\n", debugstr_w(guid
));
297 ret
= SHRegQueryUSValueW(tb_class_handle
, NULL
, NULL
, tb_name
, &tb_name_len
, TRUE
, NULL
, 0);
299 SHRegCloseUSKey(tb_class_handle
);
301 if(ret
!= ERROR_SUCCESS
)
303 ERR("Failed to get toolbar name for %s\n", debugstr_w(guid
));
307 item
.cbSize
= sizeof(item
);
308 item
.fMask
= MIIM_STRING
;
309 item
.dwTypeData
= tb_name
;
310 InsertMenuItemW(menu
, GetMenuItemCount(menu
), TRUE
, &item
);
313 SHRegCloseUSKey(classes_handle
);
314 SHRegCloseUSKey(toolbar_handle
);
318 static HMENU
create_ie_menu(void)
320 HMENU menu
= LoadMenuW(ieframe_instance
, MAKEINTRESOURCEW(IDR_BROWSE_MAIN_MENU
));
321 HMENU favmenu
= get_fav_menu(menu
);
322 WCHAR path
[MAX_PATH
];
324 add_tbs_to_menu(get_tb_menu(menu
));
326 if(SHGetFolderPathW(NULL
, CSIDL_COMMON_FAVORITES
, NULL
, SHGFP_TYPE_CURRENT
, path
) == S_OK
)
327 add_favs_to_menu(favmenu
, favmenu
, path
);
329 if(SHGetFolderPathW(NULL
, CSIDL_FAVORITES
, NULL
, SHGFP_TYPE_CURRENT
, path
) == S_OK
)
330 add_favs_to_menu(favmenu
, favmenu
, path
);
335 static void ie_navigate(InternetExplorer
* This
, LPCWSTR url
)
339 V_VT(&variant
) = VT_BSTR
;
340 V_BSTR(&variant
) = SysAllocString(url
);
342 IWebBrowser2_Navigate2(&This
->IWebBrowser2_iface
, &variant
, NULL
, NULL
, NULL
, NULL
);
344 SysFreeString(V_BSTR(&variant
));
347 static INT_PTR CALLBACK
ie_dialog_open_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
349 static InternetExplorer
* This
;
354 This
= (InternetExplorer
*)lparam
;
355 EnableWindow(GetDlgItem(hwnd
, IDOK
), FALSE
);
359 switch(LOWORD(wparam
))
361 case IDC_BROWSE_OPEN_URL
:
363 HWND hwndurl
= GetDlgItem(hwnd
, IDC_BROWSE_OPEN_URL
);
364 int len
= GetWindowTextLengthW(hwndurl
);
366 EnableWindow(GetDlgItem(hwnd
, IDOK
), len
!= 0);
371 HWND hwndurl
= GetDlgItem(hwnd
, IDC_BROWSE_OPEN_URL
);
372 int len
= GetWindowTextLengthW(hwndurl
);
378 V_VT(&url
) = VT_BSTR
;
379 V_BSTR(&url
) = SysAllocStringLen(NULL
, len
);
381 GetWindowTextW(hwndurl
, V_BSTR(&url
), len
+ 1);
382 IWebBrowser2_Navigate2(&This
->IWebBrowser2_iface
, &url
, NULL
, NULL
, NULL
, NULL
);
384 SysFreeString(V_BSTR(&url
));
389 EndDialog(hwnd
, wparam
);
396 static void ie_dialog_about(HWND hwnd
)
398 HICON icon
= LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON
), IMAGE_ICON
, 48, 48, LR_SHARED
);
400 ShellAboutW(hwnd
, wszWineInternetExplorer
, NULL
, icon
);
406 static void ie_dialog_properties(HWND hwnd
)
408 ShellExecuteW(hwnd
, NULL
, L
"inetcpl.cpl", NULL
, NULL
, 0);
412 static void add_tb_separator(InternetExplorer
*ie
)
416 ZeroMemory(&btn
, sizeof(btn
));
419 btn
.fsStyle
= BTNS_SEP
;
420 SendMessageW(ie
->toolbar_hwnd
, TB_ADDBUTTONSW
, 1, (LPARAM
)&btn
);
423 static void add_tb_button(InternetExplorer
*ie
, int bmp
, int cmd
, int strId
)
428 LoadStringW(ieframe_instance
, strId
, buf
, ARRAY_SIZE(buf
));
432 btn
.fsState
= TBSTATE_ENABLED
;
433 btn
.fsStyle
= BTNS_SHOWTEXT
;
435 btn
.iString
= (INT_PTR
)buf
;
437 SendMessageW(ie
->toolbar_hwnd
, TB_ADDBUTTONSW
, 1, (LPARAM
)&btn
);
440 static void enable_toolbar_button(InternetExplorer
*ie
, int command
, BOOL enable
)
442 SendMessageW(ie
->toolbar_hwnd
, TB_ENABLEBUTTON
, command
, enable
);
445 static void create_rebar(InternetExplorer
*ie
)
450 REBARBANDINFOW bandinf
;
452 HIMAGELIST imagelist
;
455 LoadStringW(ieframe_instance
, IDS_ADDRESS
, addr
, ARRAY_SIZE(addr
));
457 hwndRebar
= CreateWindowExW(WS_EX_TOOLWINDOW
, REBARCLASSNAMEW
, NULL
,
458 WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|RBS_VARHEIGHT
|CCS_TOP
|CCS_NODIVIDER
, 0, 0, 0, 0,
459 ie
->frame_hwnd
, (HMENU
)IDC_BROWSE_REBAR
, ieframe_instance
, NULL
);
461 rebarinf
.cbSize
= sizeof(rebarinf
);
463 rebarinf
.himl
= NULL
;
465 SendMessageW(hwndRebar
, RB_SETBARINFO
, 0, (LPARAM
)&rebarinf
);
467 ie
->toolbar_hwnd
= CreateWindowExW(TBSTYLE_EX_MIXEDBUTTONS
, TOOLBARCLASSNAMEW
, NULL
, TBSTYLE_FLAT
| WS_CHILD
| WS_VISIBLE
| CCS_NORESIZE
,
468 0, 0, 0, 0, hwndRebar
, (HMENU
)IDC_BROWSE_TOOLBAR
, ieframe_instance
, NULL
);
470 imagelist
= ImageList_LoadImageW(ieframe_instance
, MAKEINTRESOURCEW(IDB_IETOOLBAR
), 32, 0, CLR_NONE
, IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
472 SendMessageW(ie
->toolbar_hwnd
, TB_SETIMAGELIST
, 0, (LPARAM
)imagelist
);
473 SendMessageW(ie
->toolbar_hwnd
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
474 add_tb_button(ie
, 0, ID_BROWSE_BACK
, IDS_TB_BACK
);
475 add_tb_button(ie
, 1, ID_BROWSE_FORWARD
, IDS_TB_FORWARD
);
476 add_tb_button(ie
, 2, ID_BROWSE_STOP
, IDS_TB_STOP
);
477 add_tb_button(ie
, 3, ID_BROWSE_REFRESH
, IDS_TB_REFRESH
);
478 add_tb_button(ie
, 4, ID_BROWSE_HOME
, IDS_TB_HOME
);
479 add_tb_separator(ie
);
480 add_tb_button(ie
, 5, ID_BROWSE_PRINT
, IDS_TB_PRINT
);
481 SendMessageW(ie
->toolbar_hwnd
, TB_SETBUTTONSIZE
, 0, MAKELPARAM(65,50));
482 SendMessageW(ie
->toolbar_hwnd
, TB_GETMAXSIZE
, 0, (LPARAM
)&toolbar_size
);
484 bandinf
.cbSize
= sizeof(bandinf
);
485 bandinf
.fMask
= RBBIM_STYLE
| RBBIM_CHILD
| RBBIM_CHILDSIZE
;
486 bandinf
.fStyle
= RBBS_CHILDEDGE
;
487 bandinf
.cxMinChild
= toolbar_size
.cx
;
488 bandinf
.cyMinChild
= toolbar_size
.cy
+2;
489 bandinf
.hwndChild
= ie
->toolbar_hwnd
;
491 SendMessageW(hwndRebar
, RB_INSERTBANDW
, -1, (LPARAM
)&bandinf
);
493 hwndAddress
= CreateWindowExW(0, WC_COMBOBOXEXW
, NULL
, WS_BORDER
|WS_CHILD
|WS_VISIBLE
|CBS_DROPDOWN
,
494 0, 0, 100,20,hwndRebar
, (HMENU
)IDC_BROWSE_ADDRESSBAR
, ieframe_instance
, NULL
);
496 bandinf
.fMask
|= RBBIM_TEXT
;
497 bandinf
.fStyle
= RBBS_CHILDEDGE
| RBBS_BREAK
;
498 bandinf
.lpText
= addr
;
499 bandinf
.cxMinChild
= 100;
500 bandinf
.cyMinChild
= 20;
501 bandinf
.hwndChild
= hwndAddress
;
503 SendMessageW(hwndRebar
, RB_INSERTBANDW
, -1, (LPARAM
)&bandinf
);
506 static LRESULT
iewnd_OnCreate(HWND hwnd
, LPCREATESTRUCTW lpcs
)
508 InternetExplorer
* This
= (InternetExplorer
*)lpcs
->lpCreateParams
;
509 SetWindowLongPtrW(hwnd
, 0, (LONG_PTR
) lpcs
->lpCreateParams
);
511 This
->doc_host
.frame_hwnd
= This
->frame_hwnd
= hwnd
;
513 This
->menu
= create_ie_menu();
515 This
->status_hwnd
= CreateStatusWindowW(WS_VISIBLE
|WS_CHILD
|SBT_NOBORDERS
|CCS_NODIVIDER
,
516 NULL
, hwnd
, IDC_BROWSE_STATUSBAR
);
517 SendMessageW(This
->status_hwnd
, SB_SIMPLE
, TRUE
, 0);
524 static LRESULT
iewnd_OnSize(InternetExplorer
*This
, INT width
, INT height
)
526 HWND hwndRebar
= GetDlgItem(This
->frame_hwnd
, IDC_BROWSE_REBAR
);
527 INT barHeight
= SendMessageW(hwndRebar
, RB_GETBARHEIGHT
, 0, 0);
528 RECT docarea
= {0, 0, width
, height
};
530 SendMessageW(This
->status_hwnd
, WM_SIZE
, 0, 0);
532 adjust_ie_docobj_rect(This
->frame_hwnd
, &docarea
);
534 if(This
->doc_host
.hwnd
)
535 SetWindowPos(This
->doc_host
.hwnd
, NULL
, docarea
.left
, docarea
.top
, docarea
.right
, docarea
.bottom
,
536 SWP_NOZORDER
| SWP_NOACTIVATE
);
538 SetWindowPos(hwndRebar
, NULL
, 0, 0, width
, barHeight
, SWP_NOZORDER
| SWP_NOACTIVATE
);
543 static LRESULT
iewnd_OnNotify(InternetExplorer
*This
, WPARAM wparam
, LPARAM lparam
)
545 NMHDR
* hdr
= (NMHDR
*)lparam
;
547 if(hdr
->idFrom
== IDC_BROWSE_ADDRESSBAR
&& hdr
->code
== CBEN_ENDEDITW
)
549 NMCBEENDEDITW
* info
= (NMCBEENDEDITW
*)lparam
;
551 if(info
->fChanged
&& info
->iWhy
== CBENF_RETURN
)
556 V_BSTR(&vt
) = SysAllocString(info
->szText
);
558 IWebBrowser2_Navigate2(&This
->IWebBrowser2_iface
, &vt
, NULL
, NULL
, NULL
, NULL
);
560 SysFreeString(V_BSTR(&vt
));
566 if(hdr
->idFrom
== IDC_BROWSE_REBAR
&& hdr
->code
== RBN_HEIGHTCHANGE
)
570 GetClientRect(This
->frame_hwnd
, &docarea
);
571 adjust_ie_docobj_rect(This
->frame_hwnd
, &docarea
);
573 if(This
->doc_host
.hwnd
)
574 SetWindowPos(This
->doc_host
.hwnd
, NULL
, docarea
.left
, docarea
.top
, docarea
.right
, docarea
.bottom
,
575 SWP_NOZORDER
| SWP_NOACTIVATE
);
581 static LRESULT
iewnd_OnDestroy(InternetExplorer
*This
)
583 HIMAGELIST list
= (HIMAGELIST
)SendMessageW(This
->toolbar_hwnd
, TB_GETIMAGELIST
, 0, 0);
587 free_fav_menu_data(get_fav_menu(This
->menu
));
588 ImageList_Destroy(list
);
589 This
->frame_hwnd
= NULL
;
594 static LRESULT
iewnd_OnCommand(InternetExplorer
*This
, HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
596 switch(LOWORD(wparam
))
599 DialogBoxParamW(ieframe_instance
, MAKEINTRESOURCEW(IDD_BROWSE_OPEN
), hwnd
, ie_dialog_open_proc
, (LPARAM
)This
);
602 case ID_BROWSE_PRINT
:
603 if(This
->doc_host
.document
)
605 IOleCommandTarget
* target
;
607 if(FAILED(IUnknown_QueryInterface(This
->doc_host
.document
, &IID_IOleCommandTarget
, (LPVOID
*)&target
)))
610 IOleCommandTarget_Exec(target
, &CGID_MSHTML
, IDM_PRINT
, OLECMDEXECOPT_DODEFAULT
, NULL
, NULL
);
612 IOleCommandTarget_Release(target
);
617 IWebBrowser2_GoHome(&This
->IWebBrowser2_iface
);
621 IWebBrowser2_GoBack(&This
->IWebBrowser2_iface
);
624 case ID_BROWSE_FORWARD
:
625 IWebBrowser2_GoForward(&This
->IWebBrowser2_iface
);
629 IWebBrowser2_Stop(&This
->IWebBrowser2_iface
);
632 case ID_BROWSE_REFRESH
:
633 IWebBrowser2_Refresh(&This
->IWebBrowser2_iface
);
636 case ID_BROWSE_ABOUT
:
637 ie_dialog_about(hwnd
);
641 case ID_BROWSE_PROPERTIES
:
642 ie_dialog_properties(hwnd
);
647 ShowWindow(hwnd
, SW_HIDE
);
651 if(LOWORD(wparam
) >= ID_BROWSE_GOTOFAV_FIRST
&& LOWORD(wparam
) <= ID_BROWSE_GOTOFAV_MAX
)
653 LPCWSTR url
= get_fav_url_from_id(get_fav_menu(This
->menu
), LOWORD(wparam
));
656 ie_navigate(This
, url
);
658 return DefWindowProcW(hwnd
, msg
, wparam
, lparam
);
663 static LRESULT
update_addrbar(InternetExplorer
*This
, LPARAM lparam
)
665 HWND hwndRebar
= GetDlgItem(This
->frame_hwnd
, IDC_BROWSE_REBAR
);
666 HWND hwndAddress
= GetDlgItem(hwndRebar
, IDC_BROWSE_ADDRESSBAR
);
667 HWND hwndEdit
= (HWND
)SendMessageW(hwndAddress
, CBEM_GETEDITCONTROL
, 0, 0);
668 LPCWSTR url
= (LPCWSTR
)lparam
;
670 SendMessageW(hwndEdit
, WM_SETTEXT
, 0, (LPARAM
)url
);
675 static LRESULT WINAPI
ie_window_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
677 InternetExplorer
*This
= (InternetExplorer
*) GetWindowLongPtrW(hwnd
, 0);
682 return iewnd_OnCreate(hwnd
, (LPCREATESTRUCTW
)lparam
);
685 ShowWindow(hwnd
, SW_HIDE
);
688 TRACE("WM_SHOWWINDOW %lx\n", wparam
);
690 IWebBrowser2_AddRef(&This
->IWebBrowser2_iface
);
691 InterlockedIncrement(&This
->extern_ref
);
693 release_extern_ref(This
, TRUE
);
694 IWebBrowser2_Release(&This
->IWebBrowser2_iface
);
698 return iewnd_OnDestroy(This
);
700 return iewnd_OnSize(This
, LOWORD(lparam
), HIWORD(lparam
));
702 return iewnd_OnCommand(This
, hwnd
, msg
, wparam
, lparam
);
704 return iewnd_OnNotify(This
, wparam
, lparam
);
706 return process_dochost_tasks(&This
->doc_host
);
707 case WM_UPDATEADDRBAR
:
708 return update_addrbar(This
, lparam
);
710 return DefWindowProcW(hwnd
, msg
, wparam
, lparam
);
713 void register_iewindow_class(void)
717 memset(&wc
, 0, sizeof wc
);
718 wc
.cbSize
= sizeof(wc
);
720 wc
.lpfnWndProc
= ie_window_proc
;
722 wc
.cbWndExtra
= sizeof(InternetExplorer
*);
723 wc
.hInstance
= ieframe_instance
;
724 wc
.hIcon
= LoadIconW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON
));
725 wc
.hIconSm
= LoadImageW(GetModuleHandleW(0), MAKEINTRESOURCEW(IDI_APPICON
), IMAGE_ICON
,
726 GetSystemMetrics(SM_CXSMICON
), GetSystemMetrics(SM_CYSMICON
), LR_SHARED
);
727 wc
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
728 wc
.hbrBackground
= 0;
729 wc
.lpszClassName
= szIEWinFrame
;
730 wc
.lpszMenuName
= NULL
;
732 RegisterClassExW(&wc
);
735 void unregister_iewindow_class(void)
737 UnregisterClassW(szIEWinFrame
, ieframe_instance
);
740 static void create_frame_hwnd(InternetExplorer
*This
)
744 szIEWinFrame
, wszWineInternetExplorer
,
745 WS_CLIPCHILDREN
| WS_CAPTION
| WS_SYSMENU
| WS_THICKFRAME
746 | WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
,
747 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
748 NULL
, NULL
/* FIXME */, ieframe_instance
, This
);
750 create_doc_view_hwnd(&This
->doc_host
);
753 static inline InternetExplorer
*impl_from_DocHost(DocHost
*iface
)
755 return CONTAINING_RECORD(iface
, InternetExplorer
, doc_host
);
758 static ULONG
IEDocHost_addref(DocHost
*iface
)
760 InternetExplorer
*This
= impl_from_DocHost(iface
);
761 return IWebBrowser2_AddRef(&This
->IWebBrowser2_iface
);
764 static ULONG
IEDocHost_release(DocHost
*iface
)
766 InternetExplorer
*This
= impl_from_DocHost(iface
);
767 return IWebBrowser2_Release(&This
->IWebBrowser2_iface
);
770 static void DocHostContainer_get_docobj_rect(DocHost
*This
, RECT
*rc
)
772 GetClientRect(This
->frame_hwnd
, rc
);
773 adjust_ie_docobj_rect(This
->frame_hwnd
, rc
);
776 static HRESULT
DocHostContainer_set_status_text(DocHost
*iface
, const WCHAR
*text
)
778 InternetExplorer
*This
= impl_from_DocHost(iface
);
779 return update_ie_statustext(This
, text
);
782 static void DocHostContainer_on_command_state_change(DocHost
*iface
, LONG command
, BOOL enable
)
784 InternetExplorer
*This
= impl_from_DocHost(iface
);
787 case CSC_NAVIGATEBACK
:
788 enable_toolbar_button(This
, ID_BROWSE_BACK
, enable
);
790 case CSC_NAVIGATEFORWARD
:
791 enable_toolbar_button(This
, ID_BROWSE_FORWARD
, enable
);
796 static void DocHostContainer_set_url(DocHost
* iface
, const WCHAR
*url
)
798 InternetExplorer
*This
= impl_from_DocHost(iface
);
800 This
->nohome
= FALSE
;
801 SendMessageW(This
->frame_hwnd
, WM_UPDATEADDRBAR
, 0, (LPARAM
)url
);
804 static const IDocHostContainerVtbl DocHostContainerVtbl
= {
807 DocHostContainer_get_docobj_rect
,
808 DocHostContainer_set_status_text
,
809 DocHostContainer_on_command_state_change
,
810 DocHostContainer_set_url
813 static HRESULT
create_ie(InternetExplorer
**ret_obj
)
815 InternetExplorer
*ret
;
817 ret
= heap_alloc_zero(sizeof(InternetExplorer
));
819 return E_OUTOFMEMORY
;
823 DocHost_Init(&ret
->doc_host
, &ret
->IWebBrowser2_iface
, &DocHostContainerVtbl
);
825 InternetExplorer_WebBrowser_Init(ret
);
827 HlinkFrame_Init(&ret
->hlink_frame
, (IUnknown
*)&ret
->IWebBrowser2_iface
, &ret
->doc_host
);
829 create_frame_hwnd(ret
);
831 InterlockedIncrement(&obj_cnt
);
832 list_add_tail(&ie_list
, &ret
->entry
);
837 HRESULT WINAPI
InternetExplorer_Create(IClassFactory
*iface
, IUnknown
*pOuter
, REFIID riid
, void **ppv
)
839 InternetExplorer
*ret
;
842 TRACE("(%p %s %p)\n", pOuter
, debugstr_guid(riid
), ppv
);
844 hres
= create_ie(&ret
);
848 hres
= IWebBrowser2_QueryInterface(&ret
->IWebBrowser2_iface
, riid
, ppv
);
849 IWebBrowser2_Release(&ret
->IWebBrowser2_iface
);
856 /******************************************************************
857 * IInternetExplorerManager implementation
859 struct InternetExplorerManager
{
860 IInternetExplorerManager IInternetExplorerManager_iface
;
864 static inline InternetExplorerManager
*impl_from_IInternetExplorerManager(IInternetExplorerManager
*iface
)
866 return CONTAINING_RECORD(iface
, InternetExplorerManager
, IInternetExplorerManager_iface
);
869 static HRESULT WINAPI
InternetExplorerManager_QueryInterface(IInternetExplorerManager
*iface
, REFIID riid
, void **out
)
871 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), out
);
873 if (IsEqualGUID(riid
, &IID_IInternetExplorerManager
) || IsEqualGUID(riid
, &IID_IUnknown
))
875 IInternetExplorerManager_AddRef(iface
);
880 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
882 return E_NOINTERFACE
;
885 static ULONG WINAPI
InternetExplorerManager_AddRef(IInternetExplorerManager
*iface
)
887 InternetExplorerManager
*This
= impl_from_IInternetExplorerManager(iface
);
888 ULONG ref
= InterlockedIncrement(&This
->ref
);
890 TRACE("(%p) increasing refcount to %u\n", iface
, ref
);
895 static ULONG WINAPI
InternetExplorerManager_Release(IInternetExplorerManager
*iface
)
897 InternetExplorerManager
*This
= impl_from_IInternetExplorerManager(iface
);
898 ULONG ref
= InterlockedDecrement(&This
->ref
);
900 TRACE("(%p) decreasing refcount to %u\n", iface
, ref
);
904 HeapFree(GetProcessHeap(), 0, This
);
911 static HRESULT WINAPI
InternetExplorerManager_CreateObject(IInternetExplorerManager
*iface
, DWORD config
, LPCWSTR url
, REFIID riid
, void **ppv
)
913 FIXME("(%p)->(0x%x, %s, %s, %p) stub!\n", iface
, config
, debugstr_w(url
), debugstr_guid(riid
), ppv
);
918 static const IInternetExplorerManagerVtbl InternetExplorerManager_vtbl
=
920 InternetExplorerManager_QueryInterface
,
921 InternetExplorerManager_AddRef
,
922 InternetExplorerManager_Release
,
923 InternetExplorerManager_CreateObject
,
926 HRESULT WINAPI
InternetExplorerManager_Create(IClassFactory
*iface
, IUnknown
*pOuter
, REFIID riid
, void **ppv
)
928 InternetExplorerManager
*ret
;
931 TRACE("(%p %s %p)\n", pOuter
, debugstr_guid(riid
), ppv
);
933 if (!(ret
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*ret
))))
934 return E_OUTOFMEMORY
;
936 ret
->IInternetExplorerManager_iface
.lpVtbl
= &InternetExplorerManager_vtbl
;
939 hr
= IInternetExplorerManager_QueryInterface(&ret
->IInternetExplorerManager_iface
, riid
, ppv
);
940 IInternetExplorerManager_Release(&ret
->IInternetExplorerManager_iface
);
942 InterlockedIncrement(&obj_cnt
);
946 void released_obj(void)
948 if(!InterlockedDecrement(&obj_cnt
))
952 static BOOL
create_ie_window(BOOL nohome
, const WCHAR
*cmdline
)
954 InternetExplorer
*ie
;
957 hres
= create_ie(&ie
);
961 IWebBrowser2_put_Visible(&ie
->IWebBrowser2_iface
, VARIANT_TRUE
);
962 IWebBrowser2_put_MenuBar(&ie
->IWebBrowser2_iface
, VARIANT_TRUE
);
968 IWebBrowser2_GoHome(&ie
->IWebBrowser2_iface
);
973 cmdlen
= strlenW(cmdline
);
974 if(cmdlen
> 2 && cmdline
[0] == '"' && cmdline
[cmdlen
-1] == '"') {
979 V_VT(&var_url
) = VT_BSTR
;
980 V_BSTR(&var_url
) = SysAllocStringLen(cmdline
, cmdlen
);
982 /* navigate to the first page */
983 IWebBrowser2_Navigate2(&ie
->IWebBrowser2_iface
, &var_url
, NULL
, NULL
, NULL
, NULL
);
985 SysFreeString(V_BSTR(&var_url
));
988 IWebBrowser2_Release(&ie
->IWebBrowser2_iface
);
992 static HDDEDATA
open_dde_url(WCHAR
*dde_url
)
994 InternetExplorer
*ie
= NULL
, *iter
;
995 WCHAR
*url
, *url_end
;
999 TRACE("%s\n", debugstr_w(dde_url
));
1004 url_end
= strchrW(url
, '"');
1006 FIXME("missing string terminator\n");
1011 url_end
= strchrW(url
, ',');
1015 url_end
= url
+ strlenW(url
);
1018 LIST_FOR_EACH_ENTRY(iter
, &ie_list
, InternetExplorer
, entry
) {
1020 IWebBrowser2_AddRef(&iter
->IWebBrowser2_iface
);
1027 hres
= create_ie(&ie
);
1032 IWebBrowser2_put_Visible(&ie
->IWebBrowser2_iface
, VARIANT_TRUE
);
1033 IWebBrowser2_put_MenuBar(&ie
->IWebBrowser2_iface
, VARIANT_TRUE
);
1035 V_VT(&urlv
) = VT_BSTR
;
1036 V_BSTR(&urlv
) = SysAllocStringLen(url
, url_end
-url
);
1037 if(!V_BSTR(&urlv
)) {
1038 IWebBrowser2_Release(&ie
->IWebBrowser2_iface
);
1042 hres
= IWebBrowser2_Navigate2(&ie
->IWebBrowser2_iface
, &urlv
, NULL
, NULL
, NULL
, NULL
);
1046 IWebBrowser2_Release(&ie
->IWebBrowser2_iface
);
1047 return ULongToHandle(DDE_FACK
);
1050 static HDDEDATA WINAPI
dde_proc(UINT type
, UINT uFmt
, HCONV hConv
, HSZ hsz1
, HSZ hsz2
, HDDEDATA data
,
1051 ULONG_PTR dwData1
, ULONG_PTR dwData2
)
1055 TRACE("XTYP_CONNECT %p\n", hsz1
);
1056 return ULongToHandle(!DdeCmpStringHandles(hsz1
, ddestr_openurl
));
1058 case XTYP_EXECUTE
: {
1063 TRACE("XTYP_EXECUTE %p\n", data
);
1065 size
= DdeGetData(data
, NULL
, 0, 0);
1071 url
= heap_alloc(size
);
1075 if(DdeGetData(data
, (BYTE
*)url
, size
, 0) != size
) {
1076 ERR("error during read\n");
1081 ret
= open_dde_url(url
);
1088 FIXME("XTYP_REQUEST\n");
1092 TRACE("type %d\n", type
);
1098 static void init_dde(void)
1102 static const WCHAR iexploreW
[] = {'I','E','x','p','l','o','r','e',0};
1103 static const WCHAR openurlW
[] = {'W','W','W','_','O','p','e','n','U','R','L',0};
1105 res
= DdeInitializeW(&dde_inst
, dde_proc
, CBF_SKIP_ALLNOTIFICATIONS
| CBF_FAIL_ADVISES
| CBF_FAIL_POKES
, 0);
1106 if(res
!= DMLERR_NO_ERROR
) {
1107 WARN("DdeInitialize failed: %u\n", res
);
1111 ddestr_iexplore
= DdeCreateStringHandleW(dde_inst
, iexploreW
, CP_WINUNICODE
);
1112 if(!ddestr_iexplore
)
1113 WARN("Failed to create string handle: %u\n", DdeGetLastError(dde_inst
));
1115 ddestr_openurl
= DdeCreateStringHandleW(dde_inst
, openurlW
, CP_WINUNICODE
);
1117 WARN("Failed to create string handle: %u\n", DdeGetLastError(dde_inst
));
1119 if(!DdeNameService(dde_inst
, ddestr_iexplore
, 0, DNS_REGISTER
))
1120 WARN("DdeNameService failed\n");
1123 static void release_dde(void)
1126 DdeNameService(dde_inst
, ddestr_iexplore
, 0, DNS_UNREGISTER
);
1128 DdeFreeStringHandle(dde_inst
, ddestr_openurl
);
1130 DdeFreeStringHandle(dde_inst
, ddestr_iexplore
);
1131 DdeUninitialize(dde_inst
);
1134 /******************************************************************
1135 * IEWinMain (ieframe.101)
1137 * Only returns on error.
1139 DWORD WINAPI
IEWinMain(const WCHAR
*cmdline
, int nShowWindow
)
1143 BOOL embedding
= FALSE
, nohome
= FALSE
, manager
= FALSE
;
1146 static const WCHAR embeddingW
[] = {'-','e','m','b','e','d','d','i','n','g',0};
1147 static const WCHAR nohomeW
[] = {'-','n','o','h','o','m','e',0};
1148 static const WCHAR startmanagerW
[] = {'-','s','t','a','r','t','m','a','n','a','g','e','r',0};
1150 TRACE("%s %d\n", debugstr_w(cmdline
), nShowWindow
);
1160 while (*cmdline
== ' ' || *cmdline
== '\t') cmdline
++;
1161 if (!*cmdline
) break;
1163 while (cmdline
[length
] && cmdline
[length
] != ' ' && cmdline
[length
] != '\t') length
++;
1165 if (!strncmpiW(cmdline
, embeddingW
, length
))
1167 else if (!strncmpiW(cmdline
, nohomeW
, length
))
1169 else if (!strncmpiW(cmdline
, startmanagerW
, length
))
1178 hres
= CoRegisterClassObject(&CLSID_InternetExplorerManager
,
1179 (IUnknown
*)&InternetExplorerManagerFactory
, CLSCTX_SERVER
,
1180 REGCLS_SINGLEUSE
, ®_cookie
);
1182 hres
= CoRegisterClassObject(&CLSID_InternetExplorer
,
1183 (IUnknown
*)&InternetExplorerFactory
, CLSCTX_SERVER
,
1184 REGCLS_MULTIPLEUSE
, ®_cookie
);
1188 ERR("failed to register CLSID_InternetExplorer%s: %08x\n", manager
? "Manager" : "", hres
);
1195 if(!create_ie_window(nohome
, cmdline
))
1202 /* run the message loop for this thread */
1203 while (GetMessageW(&msg
, 0, 0, 0))
1205 TranslateMessage(&msg
);
1206 DispatchMessageW(&msg
);
1209 CoRevokeClassObject(reg_cookie
);