Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
SHDocVw.WebBrowser with tabs
#1
How can I open in a dialog (SHDocVw.WebBrowser with tabs) all html files of a directory?
#2
See also: SHDocVw.WebBrowser with tabs

Function dlg_tabbed_web_browser
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages

;Opens all htm and html files in a folder in separate tabs.
;Change the str files=... line below.


if(!ShowDialog("dlg_tabbed_web_browser" &dlg_tabbed_web_browser)) ret

;BEGIN DIALOG
;0 "" 0x10C80A44 0x100 0 0 433 266 "QM tabbed web browser"
;3 SysTabControl32 0x54000040 0x0 10 10 416 250 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2030009 "" "" ""

ret
;messages

type TWB_TAB ~path ~name hwndwb
ARRAY(TWB_TAB)- ta

sel message
,case WM_INITDIALOG
,str files="$qm$\web\*.htm*" ;;change this
,
,;files -> array
,ta=0
,Dir d
,foreach(d files FE_Dir)
,,TWB_TAB& r=ta[]
,,r.path=d.FileName(1)
,,r.name=d.FileName
,ta.sort(0 DTWB_sort)
,
,;array -> tabs
,int htb=id(3 hDlg)
,TCITEM ti.mask=TCIF_TEXT
,int i
,for i 0 ta.len
,,ti.pszText=ta[i].name
,,SendMessage htb TCM_INSERTITEM i &ti
,
,SelectTab htb -1 ;;none
,
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.code
,case TCN_SELCHANGE ;;a tab selected
,for(i 0 ta.len) if(ta[i].hwndwb) hid ta[i].hwndwb ;;hide all
,i=SendMessage(nh.hwndFrom TCM_GETCURSEL 0 0)
,if(i<0 or i>=ta.len) ret
,&r=ta[i]
,if(r.hwndwb)
,,hid- r.hwndwb ;;if the control already created, unhide
,,BringWindowToTop r.hwndwb
,else ;;create control and open document
,,htb=id(3 hDlg)
,,RECT rct; GetClientRect htb &rct
,,SendMessage htb TCM_ADJUSTRECT 0 &rct
,,MapWindowPoints htb hDlg +&rct 2
,,r.hwndwb=CreateControl(0 "ActiveX" "SHDocVw.WebBrowser" 0 rct.left rct.top rct.right-rct.left rct.bottom-rct.top hDlg 100+i)
,,BringWindowToTop r.hwndwb
,,r.path.setwintext(r.hwndwb)

Function DTWB_sort
Code:
Copy      Help
function# param TWB_TAB&a TWB_TAB&b

ret StrCompare(a.name b.name 1)
#3
Perfect! (like always).

Thanks a lot.
#4
Is possible set % zoom in SHDocVw.WebBrowser?
#5
Function dlg_web_browser_zoom
Code:
Copy      Help
\Dialog_Editor
function# hDlg message wParam lParam
if(hDlg) goto messages

str controls = "3"
str ax3SHD
ax3SHD="http://www.google.com"
if(!ShowDialog("dlg_web_browser_zoom" &dlg_web_browser_zoom &controls)) ret

;BEGIN DIALOG
;0 "" 0x90C80A44 0x100 0 0 327 191 "Dialog"
;3 ActiveX 0x54030000 0x0 0 0 328 170 "SHDocVw.WebBrowser"
;4 Button 0x54032000 0x0 12 174 48 14 "Zoom font"
;5 Button 0x54032000 0x0 66 174 48 14 "Zoom optical"
;END DIALOG
;DIALOG EDITOR: "" 0x2030009 "*" "" ""

ret
;messages
sel message
,case WM_INITDIALOG
,SHDocVw.WebBrowser we3
,;we3._getcontrol(id(3 hDlg))
,
,
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case 4 ;;Zoom font
,we3._getcontrol(id(3 hDlg))
,VARIANT v=4 ;;0 to 4, default 2
,we3.ExecWB(OLECMDID_ZOOM OLECMDEXECOPT_DONTPROMPTUSER v 0)
,
,case 5 ;;Zoom optical
,if(_iever<0x700) mes "supported in IE7 and later"; ret
,we3._getcontrol(id(3 hDlg))
,v=200 ;;10 to 1000 %, default 100
,we3.ExecWB(OLECMDID_OPTICAL_ZOOM OLECMDEXECOPT_DONTPROMPTUSER v 0)
,
,case IDOK
,case IDCANCEL
ret 1
#6
Thanks again.
#7
When execute

we3._getcontrol(id(3 hDlg))
,VARIANT v=0 ;;0 to 4, default 2
,we3.ExecWB(OLECMDID_ZOOM OLECMDEXECOPT_DONTPROMPTUSER v 0)

and then I open a new explorer ("www.google.com") the text is small.

Do you know why?
#8
You probably also noticed that when you change font size in IE, then new WebBrowser controls use the same font size as in IE. Probably saves in registry but I don't know where.
#9
Function dlg_web_browser_zoom
Code:
Copy      Help
,;remember font size in registry
,str fs fsrk="Software\Microsoft\Internet Explorer\International\Scripts\3"
,rget(fs "IEFontSize" fsrk 0 "" REG_BINARY)
,
,we3._getcontrol(id(3 hDlg))
,VARIANT v=0 ;;0 to 4, default 2
,we3.ExecWB(OLECMDID_ZOOM OLECMDEXECOPT_DONTPROMPTUSER v 0)
,
,;restore font size in registry
,if(fs.len) rset(fs "IEFontSize" fsrk 0 REG_BINARY)

tested on XP with IE7 and Vista with IE8.
#10
Hi Gintaras,
I used the dialog SHDocVw.WebBrowser with tabs and loaded the tabs from a folder full of html tabs. The sites are mostly journals with PDFs. The pdfs load fine but won't scroll. They actually lock up all functions of the dialog (tabs don't switch, etc). Everyone in a while, the pages advance very rapidly but then everything locks up right away again.

I tried loading up PDFs in the dlg from resources called "dlg_simple_web_browser" and it worked perfectly. Maybe the difference is that the multi-tab dialog works by opening the html files rather than navigating to the web site e.g. "c.Navigate("www.journal.com"); err"
Is the html file way faster?
Could I populate a mult-tab browser by just Selecting the Tab (SelectTab) and then navigating. Would this be slower in loading up the websites (> ~20)?

Thanks for any advice on how to get the pdfs working properly?

Stuart

ps. I am using Adobe Reader 9 and it is defaulting to opening the pdf document "in" the browser.
#11
Before last line, insert
Function dlg_tabbed_web_browser
Code:
Copy      Help
,,BringWindowToTop r.hwndwb
#12
Hi Gintaras,

Your solution worked great

Quote:Before last line, insert
Function dlg_tabbed_web_browser ?

,,BringWindowToTop r.hwndwb

I am now trying to add a back button to the dialog. With browsers with a SHDocVw.WebBrowser we3._getcontrol(h) statement you can use

the case 4 we3.GoBack
case 5 we3.GoForward
case 6 we3.Stop
case 7 we3.Refresh
case 8 we3.GoHome

but doesn't seem to be the way the multi-tab dialog with web-browser is set up. I couldn't seem to set up the equivalent in this type of dialog. Any suggestions other than sending key commands to the window?

Thanks so much again,
Stuart
#13
h=child("" "ActiveX" hDlg)

it should find the visible web browser window. Then use h with getcontrol.
#14
Thanks Gintaras,
That actually provides the strategy to do many things that I wanted with that dialog. I also came across a description of something like this in the help menu - an AMAZING resource.
Thanks,
Stuart
#15
Hi Gintaras,
I am trying to convert the dlg_tabbed_web_browser above to pre-load a a few websites rather than a folder of .htm files. Let's say www.google.com, www.bing.com, www.yahoo.com. Thought something like this existed in the forum but can't seem to figure it out. The trick is that the url's need to pre-populate the tabs and then allow the user to switch back and forth without reloading or going back to the original url, even if the user clicks through to some link in the individual tabs.
I thought it would be easy to adjust the code above but I got to admit the ta[i].hwndwb part is throwing me a bit.

Thanks for any guidance,
S
#16
This version loads web pages. Plus something more.


Attached Files
.qml   Tabbed web browser.qml (Size: 3.67 KB / Downloads: 624)
#17
Amazing!!!! Thanks so much!!!
One additional question..
Sometime I need to update the various tabs from external functions. So what I have done is give each browser control a unique global int+ in the main dialog:

Code:
Copy      Help
,,if i = 0
,,,int+ TabBrowserControl_0 = r.hwndwb
,,if i = 1
,,,int+ TabBrowserControl_1 = r.hwndwb
,,if i = 2
,,,int+ TabBrowserControl_2 = r.hwndwb

and then in the updating function do something like this for each of the Browser controls:

Code:
Copy      Help
type TWB_TAB ~path ~name hwndwb
ARRAY(TWB_TAB)- ta
int- iTab
SHDocVw.WebBrowser wbDTWB2 wbDTWB3
int i htb
RECT rct
int hDlg=win("QM tabbed web browser" "#32770")
htb=id(3 hDlg)
str+ strId
str UrlUpdate =  F"http://SampleWebPage.aspx?person_id={strId}"
int+ TabBrowserControl_0
BringWindowToTop TabBrowserControl_0
wbDTWB2._getcontrol(TabBrowserControl_0)
wbDTWB2._setevents("wbDTWB2_DWebBrowserEvents2")
wbDTWB2.Navigate(UrlUpdate)

Is this how you would do it?

Thanks,
S
#18
I would do differently. The dialog function should manage its controls, because it knows better how to do it, and because it's better to do it in its thread. External function should send a message to tell the dialog function to do it.

Function dlg_tabbed_web_browser2
Code:
Copy      Help
,case WM_APP+1
,;A macro can send this message to select a tab and load a page.
,;wParam is tab index, lParam is URL; if lParam 0, just selects tab.
,;Returns current tab index (before changing).
,;Don't send from other process.
,;EXAMPLES
,;int w=win("QM tabbed web browser" "#32770")
,;SendMessage w WM_APP+1 2 0 ;;select tab 2
,;SendMessage w WM_APP+1 1 "www.quickmacros.com" ;;select tab 1 and load URL
,
,_i=iTab
,if wParam>=0 and wParam<ta.len
,,if(wParam!=iTab) SelectTab id(3 hDlg) wParam
,,if lParam
,,,lpstr URL=+lParam
,,,wbDTWB2._getcontrol(ta[wParam].hwndwb)
,,,wbDTWB2.Navigate(@URL)
,ret _i
,

If don't want or cannot edit dialog code, this should work:
SelectTab id(3 w) iTab
URL.setwintext(id(100+iTab w))
#19
this is almost too good!!! and a great template for other dialog interactions that I do with external threads and global variables, which I know is a messy way of coding....thanks for all the examples of safe and elegant coding.
Thanks as always,
S
#20
Hi Gintaras,
Hope all is well! I still use QM to do amazing things everyday.
I was wondering if there is a good way to load up all the tabs at startup, so for the user they are pre-loaded when they go to that tab. For the example below, everything would load quickly at tab selection, but for some websites that is not the case. When I move up the control creation and navigate code up to WM_INITDIALOG, it does preload them, but there is an initial period where things look like they are going crazy, rapidly rotating through all the tabs. Then once everything is loaded, it settles down and behaves like I intend. Is there a better way to do this. Obviously, not good for user to see this. I can hide the tabs during that period but wondering if there is a better way. Also, if I have many many browser tabs, say ~30, it would be nice to now there progress in loading, i.e. when they are all done so I can unhide the controls. Or is this not the ideal way to work with this many tabs.
I also worry about resources of having so many separate ActiveX WebBrowsers - maybe there is a better way to achieve this.
Thanks,



Function dlg_tabbed_web_browser_atstartup
Code:
Copy      Help
\Dialog_Editor

;Opens several web pages in tabs.
;Change the str pagesCSV=... below.

function# hDlg message wParam lParam
if(hDlg) goto messages

out
if(!ShowDialog("" &dlg_tabbed_web_browser_atstartup 0 0 0 0 0 0 0 0 0 "dlg_tabbed_web_browser2")) ret

;BEGIN DIALOG
;0 "" 0x10CF0A48 0x100 0 0 433 265 "QM tabbed web browser"
;3 SysTabControl32 0x54000040 0x0 0 0 434 268 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2030400 "" "" ""

ret
;messages

type TWB_TAB ~path ~name hwndwb
ARRAY(TWB_TAB)- ta
int- iTab
SHDocVw.WebBrowser wbDTWB2
int i htb
RECT rct

sel message
,case WM_INITDIALOG
,max hDlg
,;specify tabs in CSV format: title, URL.
,str pagesCSV=
,;QuickMacros, www.quickmacros.com
,;Forum, http://www.quickmacros.com/forum/index.php
,;General, http://www.quickmacros.com/forum/forumdisplay.php?fid=8
,;Programming, http://www.quickmacros.com/forum/forumdisplay.php?fid=9
,;Extensions, http://www.quickmacros.com/forum/forumdisplay.php?fid=14
,;My QM, http://www.quickmacros.com/forum/forumdisplay.php?fid=15
,;Computer World, http://www.quickmacros.com/forum/forumdisplay.php?fid=16
,;Wish List, http://www.quickmacros.com/forum/forumdisplay.php?fid=17
,;Bug Reports,http://www.quickmacros.com/forum/forumdisplay.php?fid=18
,;Post, http://ftp.quickmacros.com/forum/showthread.php?tid=6402&pid=31106
,;
,
,;add tabs
,ICsv csv=CreateCsv(1); csv.FromString(pagesCSV)
,htb=id(3 hDlg)
,TCITEMW ti.mask=TCIF_TEXT
,for i 0 csv.RowCount
,,TWB_TAB& r=ta[]
,,r.path=csv.Cell(i 1)
,,ti.pszText=@csv.Cell(i 0)
,,SendMessage htb TCM_INSERTITEMW i &ti
,,TabControlGetClientRect htb hDlg rct
,,r.hwndwb=CreateControl(0 "ActiveX" "SHDocVw.WebBrowser" 0 rct.left rct.top rct.right-rct.left rct.bottom-rct.top hDlg 100+i)
,,BringWindowToTop r.hwndwb
,,wbDTWB2._getcontrol(r.hwndwb)
,,wbDTWB2._setevents("wbDTWB2_DWebBrowserEvents2")
,,wbDTWB2.Navigate(r.path)
,,
,,
,,
,,
,,
,,;SelectTab htb i ;;none
,iTab=-1
,;SelectTab htb -1 ;;none
,SelectTab htb 0 ;;disable this line if don't want to load page now

,case WM_APP+1
,;A macro can send this message to select a tab and load a page.
,;wParam is tab index, lParam is URL; if lParam 0, just selects tab.
,;Returns current tab index (before changing).
,;Don't send from other process.
,;EXAMPLES
,;int w=win("QM tabbed web browser" "#32770")
,;SendMessage w WM_APP+1 2 0 ;;select tab 2
,;SendMessage w WM_APP+1 1 "www.quickmacros.com" ;;select tab 1 and load URL
,
,_i=iTab
,if wParam>=0 and wParam<ta.len
,,if(wParam!=iTab) SelectTab id(3 hDlg) wParam
,,if lParam
,,,lpstr URL=+lParam
,,,wbDTWB2._getcontrol(ta[wParam].hwndwb)
,,,wbDTWB2.Navigate(@URL)
,ret _i    
,
,
,case WM_DESTROY
,
,case WM_SIZE
,htb=id(3 hDlg)
,GetClientRect hDlg &rct; MoveWindow htb rct.left rct.top rct.right-rct.left rct.bottom-rct.top 1
,TabControlGetClientRect htb hDlg rct
,for(i 0 ta.len) if(ta[i].hwndwb) MoveWindow ta[i].hwndwb rct.left rct.top rct.right-rct.left rct.bottom-rct.top 0
,
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case [101,102,103,104]
,err-
,int hax=ta[iTab].hwndwb
,wbDTWB2._getcontrol(hax)
,sel wParam
,,case 101 wbDTWB2.GoBack
,,case 102 wbDTWB2.Refresh
,,case 103 wbDTWB2.Navigate(ta[iTab].path) ;;Home. Load the start page of this tab.
,,case 104 if(inp(_s "URL:" "Go to" "" 0 "" 0 hDlg)) wbDTWB2.Navigate(_s)
,err+
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.code
,case TCN_SELCHANGE ;;a tab selected
,htb=nh.hwndFrom
,for(i 0 ta.len) if(ta[i].hwndwb) hid ta[i].hwndwb ;;hide all
,i=SendMessage(htb TCM_GETCURSEL 0 0); if(i<0 or i>=ta.len) ret
,iTab=i
,&r=ta[i]
,if(r.hwndwb)
,,hid- r.hwndwb ;;if the control already created, unhide
,,BringWindowToTop r.hwndwb
,else ;;create control and open document
,,TabControlGetClientRect htb hDlg rct
,,r.hwndwb=CreateControl(0 "ActiveX" "SHDocVw.WebBrowser" 0 rct.left rct.top rct.right-rct.left rct.bottom-rct.top hDlg 100+i)
,,BringWindowToTop r.hwndwb
,,wbDTWB2._getcontrol(r.hwndwb)
,,wbDTWB2._setevents("wbDTWB2_DWebBrowserEvents2")
,,wbDTWB2.Navigate(r.path)

;BEGIN MENU
;&Back : 101
;&Reload : 102
;&Home : 103
;&GoTo... :104
;END MENU


Forum Jump:


Users browsing this thread: 1 Guest(s)