|
Not a very elegant solution. I've actually found a better solution already:
Use OleRunInstance to start an instance of IE, this gives you access to an IWebbrowser2 object. On this object the method Show_toolbar can be called with which toolbars can be made visible (you can identify the toolbars with there GUID). This can be done once from the installer, after you've registered the toolbar-dll
Now to make the toolbar take up a whole new line. This needs to be done from within your toolbar. In the function ShowDW it is posiible to send a message to the tollbars parent (m_hWndParent) this parent is the rebarcontrol managing all the bands. Now armed with your Band ID (m_dwBandID) you can query your parent for your index (A REBAR control message) and with this index you can query the rebarcontrol for your rebar style and modify this style to als contain the flag RBBS_BREAK. This makes your toolbar to always take up a new line when it is switced from disabled to enabled.
|
|
|
|
|
I've been getting some questions about how exactly to get a toobar to display on a new line, so here is a codesnippet:
STDMETHODIMP CProclareBar::ShowDW(BOOL fShow)
{
//Here the rebarstyle RBBS_BREAK is set in the parent, so that the toolbar
// is always made completely visible when activated.
//first retrieve the index of the toolbar
int Index = SendMessage(m_hWndParent, RB_IDTOINDEX, m_dwBandID, 0);
if (Index != -1)
{
// fill a rbbi so that the current style is retrieved.
REBARBANDINFO rbbi;
rbbi.cbSize = sizeof(REBARBANDINFO);
rbbi.fMask = RBBIM_STYLE;
//retrieve the style
if (SendMessage(m_hWndParent, RB_GETBANDINFO, Index, (long)&rbbi))
{
//add the RBBS_BREAK style to the style
rbbi.fMask = RBBIM_STYLE;
rbbi.fStyle |= RBBS_BREAK;
//send the style to the parent.
long rc = SendMessage(m_hWndParent, RB_SETBANDINFO, Index, (long)&rbbi);
}
}
HRESULT hr = S_OK;
m_bShow = fShow;
ShowWindow(m_hWnd, m_bShow ? SW_SHOW : SW_HIDE);
return hr;
}
|
|
|
|
|
but the toolbar is not remaining visible after launching then IE ?
|
|
|
|
|
This makes the toolbar appear on a new line when it is made visible...
If you want the toolbar to start visible, you can use the the follwing functions from an installer:
//Runs an instance of Internet explorer and let's the pIE point to the Iwebbrowser2 interface
int RunIe( IWebBrowser2 *&pIE )
{
if (pIE == NULL) // Can only start one instance
{
CoInitialize( NULL );
// Create an instance of Internet Explorer
HRESULT hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2, (void**)&pIE);
if (SUCCEEDED(hr))
{
// Make IE visible
pIE->put_Visible(VARIANT_TRUE);
return TRUE;
}
}
return FALSE;
}
// in: CLSID-string of a IE-Bar element (toolbar or toolband), and IWebBrowser interface
void ShowBandObject(IWebBrowser2 *pIE, WCHAR *pszBarCLSID, bool bShow = true)
{
// Show
VARIANT vtBandGUID;
VARIANT vtShow;
VARIANT vtNotUsed;
vtBandGUID.vt = VT_BSTR;
vtBandGUID.bstrVal = SysAllocString( pszBarCLSID );
vtShow.vt = VT_BOOL;
vtShow.boolVal = bShow;
vtNotUsed.vt = VT_INT;
vtNotUsed.intVal = 1;
HRESULT hr = pIE->ShowBrowserBar(&vtBandGUID, &vtShow, &vtNotUsed);
SysFreeString(vtBandGUID.bstrVal);
}
If you invoke these functions from another program, they will open IE and make the toolbar visible
|
|
|
|
|
I looked at how google is doign theirs (did you notice you can't tab to their search edit control). They package their DLL in a cab, download it, install it from the cab, then embed a webbrowser into the webpage using the GUID of the webbrowser. Then they call ShowBrowserBar() with the guid of their control. Then they close the window and open a new one with the toolbar already visible.
Now you can do it too.
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
hi
i have created a toolbar menu with toolbuttons and popupmenus like ie's main menu
and when i need shortcuts like Alt+S and Ctrl+B
i used ie's main window proc hook to get keyboard input
and it worked.
now im looking for a better way which is less dangerous for ie
i saw TranslateAcceleratorIO in InputObject
i have no edit box or any other input object in my toolbar
so possible to get those input without them?
thanks in advance
Ozgur YASAR
Mikro YAZILIMEVi
Istanbul / Turkiye
|
|
|
|
|
You would need to create a hidden window and have it catch the TranslateAccelertatorIO information which it could then wrote to the correct actions on your toolbar and popup menus. Look at the MS KBbar.exe example in their Knowledgebase.
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
I've just built my toolband(toolband.dll)
How do I to add it to IE?
Shin
|
|
|
|
|
Once you have it built and deployed, you have to run it against RegSrv32.exe to register it on the target system for IE to find it. If IE has already enumerated the toolbars and bands you may need to logoff and log back on or if you have a new version of IE you can set a registry key that IE will pickup and re-enumerate the listings without the need to logoff or kill the explorer windows.
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
Thanks
|
|
|
|
|
I have tried to add a button to the band.
Unfotunately the band is displayed without
any button.
I am listing below the method used in creating
the band and adding the button and would
appreciate it very much if
the reason(s) could be explained.
Thanks for your help
************************************************************************/
BOOL CToolBand::RegisterAndCreateWindow(void)
{
//If the window doesn't exist yet, create it now.
if(!m_hWnd)
{
//Can't create a child window without a parent.
if(!m_hwndParent)
{
return FALSE;
}
//If the window class has not been registered, then do so.
WNDCLASS wc;
if(!GetClassInfo(g_hInst, TB_CLASS_NAME, &wc))
{
ZeroMemory(&wc, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(192, 192, 192));
wc.lpszMenuName = NULL;
wc.lpszClassName = TB_CLASS_NAME;
if(!RegisterClass(&wc))
{
//If RegisterClass fails, CreateWindow below will fail.
}
}
RECT rc;
GetClientRect(m_hwndParent, &rc);
//Create the window. The WndProc will set m_hWnd.
CreateWindowEx( 0,
TB_CLASS_NAME,
NULL,
WS_CHILD | WS_CLIPSIBLINGS,// | WS_BORDER,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
m_hwndParent,
NULL,
g_hInst,
(LPVOID)this);
}
SendMessage (m_hWnd, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
TBBUTTON tbb[1];
char szBuf[16];
int iCopy;
//add button string
LoadString(g_hInst, STD_COPY, szBuf, 16);
// Save room for second null terminator
szBuf[lstrlen(szBuf) + 1] = 0; // Double null terminate
iCopy = SendMessage(m_hWnd, TB_ADDSTRING, 0, (LPARAM) (LPSTR) szBuf);
// Fill TBBUTTON array
tbb[0].iBitmap = -1;
tbb[0].idCommand = STD_COPY;
tbb[0].fsState = TBSTATE_ENABLED;
tbb[0].fsStyle = TBSTYLE_BUTTON;
tbb[0].dwData = 0;
tbb[0].iString = iCopy;
SendMessage (m_hWnd, TB_ADDBUTTONS, (WPARAM) 1, (LPARAM) (LPTBBUTTON) &tbb);
SendMessage (m_hWnd, TB_AUTOSIZE, 0, 0);
return (NULL != m_hWnd);
}
================= END ========
|
|
|
|
|
Have you tried stepping through the code? Are you actually getting inside the first if block? I can't tell since I dont' know what the values of m_hWnd and m_hWndParent are. Also, g_hInst should be _Module.GetResourceInstance(). The other problem I see is that you have set the text for the button but not the image. Since text is not displayed except if some extended styles are set and a button style is set, the text that you have set will only show as a tooltip. Look at the BTNS_SHOWTEXT style below.
BTNS_SHOWTEXT Version 5.81. All buttons can have text, but only those buttons with the BTNS_SHOWTEXT button style will display it. This button style must be used with the TBSTYLE_LIST style, and the TBSTYLE_EX_MIXEDBUTTONS extended style. If you set text for buttons that do not have the BTNS_SHOWTEXT style, the toolbar control will automatically display it as a tooltip when the cursor hovers over the button. This feature allows your application to avoid handling the TBN_GETINFOTIP notification for the toolbar.
As a side note; Even though my example created from the wizard uses an api call to create a label, you can use the CWindow or CContainedWindow class to build up your toolbar.
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
I know your are very busy but I've got a last question for you :
I need to connect a toolbar and a CommBand (the toolbar has to lanch functions of the CommBand)
Each one is hosted in the same IE window
How can I retrieve a pointer on the CommBar ?
I've try to implement the QueryInterface fonction the CommBand (it didn't work)
I've try to call QueryIntface in the toolbar with :
- a IServiceProviderPtr (from a)
- a IInputObjectSitePtr
- a IWebBrowser2Ptr
each call gives me NULL pointer
Finally I tried to lanch the Commbar with "CoCreateInstance" witch gave me a valid pointer but not on the good CommBar
Do you know were I can find any informations in the msdn ?
Sorry for making you losing your time...
Dim
A+
|
|
|
|
|
I've just find the solution of my problem in the second chapter of my Com book....
I've forgot to check in it...
so I used "CoGetClassObject" to get the factory of my second band
then I used "CreateInstance" on the factory to get the proper interface with the commbar
It's working fine and I hope that everything is correct
Bye and thanks for your articles they are really helpful
Dim
A+
|
|
|
|
|
like Remco, I'm trying to capture the backspace in an explorer toolbar.
I've try to implement the IInputObject (like it is said in the article you give to Remco) but it is not working...
The IInputObject functions are never called...
I've try several method to implement my bar (all use a CAxWindow with a HTLM control) :
- use a specific class derived from a CWindowImpl (like your CHTMlPageWnd)
- use the implementation of CWindowImpl directly in the band object provided by your atl wizard
I really need some help cause I don't know what to try next
thanks
Dim
|
|
|
|
|
I'm pretty strapped for time right now but to help you out in the meantime you should look at the MS KB article that gives you an example project of what to do called kbbar.exe
KB:Q246234 http://support.microsoft.com/support/kb/articles/q246/2/34.asp
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
thanks for the answer
Actually I forgot the idea to use an html page in my toolbar.
I used kbbar to build a more "normal" one.
The only problem i'm encountering is that i'm not able to change the ComboEx control into a Cedit control (it doesn't want to take the focus)...
thanks again
Dim
A+
|
|
|
|
|
Getting the CEdit control involves you asking your ComboBox for the Edit control and then setting focus to it in your code.
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
I was tring to create the band by attaching a CDialog by pass the m_hWnd of the dialog to the band..
The code compiled fine, but the execution is not.
The band would not display my dialog, and IE freezed when I try to resize the band. Any idea how I implement the band in MFC??
BOOL Csbar::RegisterAndCreateWindow()
{
RECT rect;
::GetClientRect(m_hWndParent, &rect);
CMyDialog myDialog;
m_hWnd = myDialog.GetSafeHwnd();
return ::IsWindow(m_hWnd);
}
|
|
|
|
|
Assuming that this is the only problem; you have called the GetSafeHwnd method before you have called the dialog class' Create method, so the HWND for the dialog is not valid yet. Plus after the method exits your myDialog object will be destroyed, which will cause other problems.
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
Thanks for pointing that out..
I changed my code and use the modeless dialog mothod to create a dialog, but now I have a compile error in the CDialog::Create(IDD_MYDIALOG, this). I never had this kinda error before in other applications.
D:\temp\thebar\MyBand2.cpp(44) : error C2664: 'int __thiscall CDialog::Create(const char *,class CWnd *)' : cannot convert parameter 1 from 'const int' to 'const char *'
I included a dialog resource and changed my code like:
The header file:
class ATL_NO_VTABLE CMyBand2 :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyBand2, &CLSID_MyBand2>,
public IDeskBand,
public IObjectWithSite,
public IPersistStream,
public IDispatchImpl<IMyBand2, &IID_IMyBand2, &LIBID_THEBARLib>
{
public:
CMyBand2();
DECLARE_REGISTRY_RESOURCEID(IDR_MYBAND2)
.......
.......
.......
protected:
DWORD m_dwBandID;
DWORD m_dwViewMode;
BOOL m_bShow;
BOOL m_bEnterHelpMode;
HWND m_hWndParent;
HWND m_hWnd;
IInputObjectSite* m_pSite;
CmyDlg *m_mydlg;
};
The cpp file:
BOOL CMyBand2::RegisterAndCreateWindow()
{
RECT rect;
::GetClientRect(m_hWndParent, &rect);
m_mydlg = new CmyDlg;
m_mydlg->Create(IDD_DIALOGBAR, this);
m_hWnd = m_mydlg->GetSafeHwnd();
return ::IsWindow(m_hWnd);
}
|
|
|
|
|
You can get around the first error my using MAKEINTRESOURCE, you will get a second error since your band is not a CWnd derived object. You will need to get a CWnd* from the m_hWndParent variable by using CWnd::FromHandle
Cheers,
-Erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My thoughts are my own and reflect on no other.
|
|
|
|
|
Thanks for the help Erik!
I've successfully compiled w/o using MAKEINTRESOURCE and it worked!
However, I found out that a AFX_MANAGE_STATE(AfxGetStaticModuleState()) must be added in the begging of the RegisterAndCreateWindow() function or IE will crash;
It is needed for using MFC.
CMyDialog* myToolBar;
BOOL CMyCoolBar::RegisterAndCreateWindow()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
RECT rect;
::GetClientRect(m_hWndParent, &rect);
CWnd* pParent = CWnd::FromHandle(m_hWndParent);
myToolBar = new CMyToolBar;
if (!myToolBar->Create(IDD_DIALOGBAR, pParent))
return false;
m_hWnd = myToolBar->GetSafeHwnd();
return ::IsWindow(m_hWnd);
}
|
|
|
|
|
do you have code that adds controls to erik's toolbar using MFC controls?
(I am completely new to MFC so bare with me...)
If I want to put a textbox and button, for example. In your example, you are adding a dialog box type window (CMyDialog) in which you have other controls, correct?
|
|
|
|
|
Is there a way to switch off the desk band title as default?
Thanks in advance ,
Thomas
I am a signature virus!
Help me spread and copy me to your sig!
|
|
|
|
|