This is getting interesting. I suddenly thought maybe Chrome allows parameters to be passed and indeed there are, tons of it. Here are the switches:
http://peter.sh/experiments/chromium-command-line-switches/
As for forcing Chrome to open on a new window instead of the existing one as a tab, it is --new-window
I also updated the sample below to know whether the operation is successful or not so it won't accidentally open any other active window aside from our target.
Later:
As for my problem to get rid of Chrome's internal titlebar, the trick came out to be very easy. All we need to do is move the chrome up from within our form that its own internal titlebar cannot be seen anymore, and thus rendering it likewise immovable.
Check the codes below, adjust lnMove value based on how you set up your Chrome on your end. Since in mine I show my bookmarks, then my adjustment is 100. Maybe on the link I gave above on the command switches, there are commands to hide those, but I did not check anymore. :)
======
Sparked by last week's thread inside Foxite Forum about placing an IE Browser inside VFP Form, I thought to myself it would be cool to put Google Chrome inside our form for a change.
Also, this will ensure that most probably a webpage can be displayed properly being Chrome is always up to date with changes introduced now and then, as compared to IE that has been left far behind and is giving developers now some headache to fix it via Registry tweaks.
Googling does not give me any result on how this new sudden thought of mine can be done as I never found any that shows how to achieve this without downloading and working on extension designed to provide automation to google. But I simply wanted chrome to be inside our VFP form using stock VFP commands and function plus utilizing WinAPIs.
I knew for a fact beforehand that this one is not as simple as placing other app inside our form like what I have shown in http://sandstorm36.blogspot.com/2014/05/3rd-party-apps-from-within-our-forms.html
For among its obstacles is that Chrome browser creates several processes when you open it. This can be seen via Task Manager so using its process ID (PID) is not a good way to go. Although originally that is where my first few thoughts went.
Next is Chrome might open several tabs depending on your local setting if you set it to remember the previous tabs opened when you close it, via "Continue where you left off".
Further, Google Chrome Browser is an entirely separate beast, so to speak. After I found the way to bring it inside our VFP form, belatedly I realize that it does not respect Windows Styles so while we can put it inside our VFP form, it is somewhat useless to me unless I can hide its TitleBar to disallow its further movements.
Maybe you will ask me, what is the purpose of placing chrome inside VFP form? Honestly, I do not have a use on my end as I never needed this nor the IE browser inside our form due to very slow internet services here in this country where I am working. But I have to satiate my curiosity for if I don't, then it will bug me now and then when the thoughts interfere on my day to day job. I simply have to satisfy my curiosity on how this can be done; so I can move on with new lines of thought. Or else I will be stuck thinking about this now and then.
Anyway, it is fun finding a way to bring it inside VFP form. Plus I learn new WinAPIs in the process just to make this possible.
I am shelving this now and will work on real things that are important. I am making this post so if anyone got an interest to even just find out how this can be done and maybe tries to enhance this, then this can maybe serve as your starting point. Codes are below:
Public oForm
oForm = Createobject('form1')
oForm.Show()
Define Class form1 As Form
Height
= 650
Width = 900
Caption = "Chrome Inside VFP Form"
Desktop = .T.
AutoCenter = .T.
controlbox = .t.
windowstate = 2
Add Object cmdexit As CommandButton
With ;
Top = 620, Left = 10, Caption = 'exit', Width = 84, Height = 24,;
Anchor = 6
Anchor = 6
Procedure cmdexit.Click
_Screen.ActiveForm.release
Endproc
Procedure
Load
Declare
Integer FindWindow In user32;
STRING lpClassName, String lpWindowName
Declare Integer GetActiveWindow In user32
Declare Integer GetWindow In user32 Integer HWnd, Integer wFlag
Declare Integer GetWindowLong In User32 Integer HWnd, Integer nIndex
Declare Integer GetWindowTextLength
In user32 Integer HWnd
Declare
Integer IsWindow In user32 Integer HWnd
Declare
Integer IsWindowVisible In user32 Integer HWnd
Declare
Integer GetWindowText In user32;
INTEGER HWnd, String @lpString, Integer cch
Declare Integer ShellExecute In shell32.Dll ;
INTEGER hndWin, ;
STRING cAction, ;
STRING cFileName, ;
STRING cParams, ;
STRING cDir, ;
INTEGER nShowWin
Declare Integer SetWindowLong In user32 Integer HWnd,;
INTEGER nIndex, Integer dwNewLong
Declare Integer SetWindowPos In user32;
INTEGER HWnd,;
INTEGER hWndInsertAfter,;
INTEGER x,;
INTEGER Y,;
INTEGER cx,;
INTEGER cy,;
INTEGER uFlags
Declare Integer SetParent In user32;
INTEGER hWndChild,;
INTEGER hWndNewParent
Declare Sleep In kernel32 Integer
Declare
SwitchToThisWindow
In user32;
INTEGER hWindow, Integer fAltTab
#Define GW_HWNDFIRST 0
#Define GW_HWNDLAST
1
#Define GW_HWNDNEXT
2
Endproc
Procedure
KeyPress
Lparameters
nKeyCode, nCtrlShift
If m.nKeyCode = 27
_screen.ActiveForm.release
Endif
Endproc
Procedure
Init
Local
lcURL
lcURL
= 'www.google.com
--new-window '
ShellExecute(0,'open','chrome.exe',m.lcURL,'',1)
Activate Window (Thisform.Name)
Sleep(1000)
Thisform.SearchProcess()
Endproc
Procedure
SearchProcess()
SwitchToThisWindow(Thisform.HWnd, 0)
With This
Local
hWinActive, hWindow, lcWinText, lSuccess, lnMove
hWinActive
= GetActiveWindow()
hWindow = -1
lSuccess = .F.
Do While hWindow <> GetWindow(hWinActive, GW_HWNDLAST)
If hWindow = -1
hWindow = GetWindow(hWinActive, GW_HWNDFIRST)
Else
hWindow = GetWindow(hWindow, GW_HWNDNEXT)
Endif
If
IsWindow(hWindow)<>0 And IsWindowVisible(hWindow)<>0;
And
GetWindowTextLength(hWindow) > 0
lcWinText = .GetWinText(hWindow)
nHwnd = FindWindow(Null, m.lcWinText)
If 'Google Chrome' $ m.lcWinText
lSuccess
= .T.
Exit
Endif
Endif
Enddo
If
m.lSuccess
lnStyle
= GetWindowLong(m.nHwnd, -6)
SetWindowLong(m.nHwnd, -16, Bitxor(lnStyle, 0x00400000))
* The trick to hide the pesky
built-in titlebar of chrome is to
* move chrome up that it won't
display the titlebar anymore. Since
there is a difference in settings
* on each of our machines such as
in my end, my bookmarks are shown, then here is my setting
* Adjust it based on your end
settings of Chrome
lnMove = 100
With This
SetParent(m.nHwnd,.HWnd)
SetWindowPos(m.nHwnd, 1, 0, -m.lnMove, .Width,;
SYSMETRIC(2) ,0x0040)
SYSMETRIC(2) ,0x0040)
Endwith
Endif
Endwith
Endproc
Function GetWinText(hWindow)
Local lnBufsize, lcBuffer
lnBufsize
= 1024
lcBuffer = Repli(Chr(0), lnBufsize)
lnBufsize = GetWindowText(hWindow, @lcBuffer, lnBufsize)
Return Iif(lnBufsize=0, "", Left(lcBuffer,lnBufsize))
Endfunc
Enddefine
As a guide on how I achieve this, it involves forcefully opening a URL to Chrome via ShellExecute(), cycling to all active windows (Chrome, VFP, Explorer, etc.) until it finds Chrome, and getting its corresponding window handle so we can put a hold on to it.
As for Chrome, depending on the speed of the connection, you may get the internal caption of the newly opened Tab or if it is slow, you will get "New Tab - Google Chrome". In which case, to ensure that no matter what we can know if it is chrome is to look for the word Google Chrome as that will always be a part of its internal caption.
Aside from the purpose of my usage of those APIs above, I posted the above as I deem it is also good for interested readers to study each APIs I used there as that may come handy on other needs as well.
Cheers!
As for Chrome, depending on the speed of the connection, you may get the internal caption of the newly opened Tab or if it is slow, you will get "New Tab - Google Chrome". In which case, to ensure that no matter what we can know if it is chrome is to look for the word Google Chrome as that will always be a part of its internal caption.
Aside from the purpose of my usage of those APIs above, I posted the above as I deem it is also good for interested readers to study each APIs I used there as that may come handy on other needs as well.
Cheers!
Hi pal. Is it posible to manage gmail with VFP?
ReplyDeleteHi friend, very good your post and what you've done with Visual FoxPro and Google Chrome.
ReplyDeleteI want to tell the inconvenience that I have that I could not resolve this issue. If the form previously think so, and then from an attempt button opening the chrome, I could not make him do it on a window on Fox, I could not dimension it a part of the form and not on the whole form, and but what I happens is that I open the browser (Chrome) and not on the form.
If I can help a little with this theme you'll thank.
I am Richard of Argentina.
Thanks and regards
This response is very late. I apologize, I seldom check my posts after I posted those and I have not realized there are two queries here already. Looking at tge dates though, I will presume that a solution to both has already been found.
ReplyDeleteEstimado necesito contactarme contigo lo mas pronto posible, Te dejo mi correo caridi23@hotmail.com
ReplyDelete