|
Hi All,
Can anybody help me out in creating a toolbar in a regular DLL. I have two
modules, first the main exe file, and the second is the DLL.
the Main app loads the DLL, and then invokes CreateToolBar(HWND hWnd), and
passed AfxGetApp()->m_pMainWnd->m_hWnd as the handle of the mainframe window...
But the code to create toolbar asserts... so i tried to comment code which
does the docking part. Now the code does not assert but toolbar is not shown.
I even tried to use ShowWindow(SW_SHOW) on it, but no result...
Please any help in this regard would be great...
Thanks in advance,
Mohit
|
|
|
|
|
I take it that the toolbar resource is in the DLL? If it is, make sure that before creating the toolbar that you have switched to the DLL's resources.
Take a look at the AFX_MANAGE_STATE() macro in the MSDN.
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
Hi Allen,
Lemme explain a bit more... The CreateToolBar() method is a member of CPlug_In_App class within the DLL... and this method is responsible for creating the toolbar... not the EXE... I had put AFX_MANAGE_STATE(.....) macro in this function.. but in vain... still the code does not asert but toolbar is not shown... i have comented the code for docking the toolbar... is it not possible to dock the toolbar from within the DLL??? i don't think so.. something must be wrong.. here is the code... the OnCmdMsg() calls
createtoolbar() method... is something wrong????
// I am passing AfxGetApp()->m_pMainWnd->m_hWnd... to the DLL which is then casted to (CMainFrame *) ---->>> m_pFrame
// m_pFrame is CMainFrame *
BOOL CPlug_In_1App::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
#ifdef DEBUG
TRACE("Called CPlug_In_1App::OnCmdMsg() method\n");
#endif
if (!CreatePlugInToolBar())
{
AfxMessageBox("Could not create PlugIn_1's toolbar");
}
// TODO: Add your specialized code here and/or call the base class
return CWinApp::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
bool CPlug_In_1App::CreatePlugInToolBar()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_bIsToolBarCreated)
{
if (!m_wndPlugInToolBar.CreateEx(m_pFrame, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_SIZE_DYNAMIC) ||
!m_wndPlugInToolBar.LoadToolBar(IDR_PLUGIN_1))
{
#ifdef DEBUG
TRACE0("Failed to create toolbar\n");
#endif
return false; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to be dockable
m_wndPlugInToolBar.SetOwner(m_pFrame);
// m_wndPlugInToolBar.EnableDocking(CBRS_ALIGN_ANY);
// EnableDocking(CBRS_ALIGN_ANY);
// m_pFrame->DockControlBar(&m_wndPlugInToolBar);
m_wndPlugInToolBar.ShowWindow(SW_SHOW);
m_bIsToolBarCreated = TRUE;
}
return true;
}
Thanks in advance...
-Mohit
|
|
|
|
|
I tackled this problem in one of my own apps. Here is the code I had to load the toolbars from the main program and dock them. Note that you may need to call ShowControlBar() to cause the toolbar(s) to be displayed the first time you run your code.
CToolBar **m_pTB ;
int m_ToolbarCount ;
void CMainFrame::LoadDLLToolbars()
{
CToolBar *last = &m_wndMainToolBar ;
int count = 0 ;
for (int DLL_index = 0 ; DLL_index < refineDLLs ; DLL_index++)
{
if (refineDLL[DLL_index].DLLGetToolbarCount != 0 && refineDLL[DLL_index].DLLGetToolbar != NULL)
{
count += refineDLL[DLL_index].DLLGetToolbarCount() ;
}
}
if (count > 0)
{
m_pTB = new CToolBar*[count] ;
m_DLLIndexes = new int[count] ;
}
int index = 0 ;
for (DLL_index = 0 ; DLL_index < refineDLLs ; DLL_index++)
{
if (refineDLL[DLL_index].DLLGetToolbarCount != 0 && refineDLL[DLL_index].DLLGetToolbar != NULL)
{
for (int i = 0 ; i < refineDLL[DLL_index].DLLGetToolbarCount() ; i++)
{
m_pTB[index] = refineDLL[DLL_index].DLLGetToolbar(i, this) ;
DockControlBar(m_pTB[index]) ;
last = m_pTB[index] ;
m_DLLIndexes[index] = DLL_index ;
index++ ;
}
}
}
m_ToolbarCount = count ;
}
CMainFrame::~CMainFrame()
{
for (int i = 0 ; i < m_ToolbarCount ; i++)
delete m_pTB[i] ;
delete []m_pTB ;
delete []m_DLLIndexes ;
}
int DLLGetToolbarCount()
{
return 1 ;
}
CToolBar* DLLGetToolbar(int index, CWnd *pMP)
{
if (index != 0)
return NULL ;
HINSTANCE hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
CToolBar *pTB = new CToolBar ;
if (!pTB->CreateEx(pMP, TBSTYLE_FLAT, WS_CHILD | CBRS_ALIGN_TOP, CRect(0, 0, 0, 0), IDR_TRAYTOOLBAR) ||
!pTB->LoadToolBar(IDR_TRAYTOOLBAR))
{
TRACE0("Failed to create toolbar\n");
AfxSetResourceHandle(hInstance);
return NULL ;
}
pTB->SetBarStyle(pTB->GetBarStyle() | CBRS_BORDER_3D) ;
pTB->EnableDocking(CBRS_ALIGN_ANY);
pTB->SetWindowText("TraySetup & Communication");
pTB->EnableToolTips(TRUE) ;
g_pTraySetupToolbar = pTB ;
AfxSetResourceHandle(hInstance);
return pTB ;
}
Hope it helps.
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
Hi Allen,
I tried it, but now it asserts at CDockContext::CDockContext()...
ASSERT(pBar->m_pDockSite != NULL);
The docksite for my toolbar is NULL....
This code is called by the EnableDocking Method()....
There is really something wrong... Is it valid to pass AfxGetApp()->m_pMainWnd->m_hWnd to DLL's fucntion... and then convert it into (CWnd *) and then use it as the mainframe???
Please help in this...
Now my code is...
bool CPlug_In_1App::CreatePlugInToolBar()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HINSTANCE hInstance = AfxGetResourceHandle();
// set resource handle to ourselves (the DLL)
AfxSetResourceHandle(theApp.m_hInstance);
if (!m_wndPlugInToolBar.CreateEx(m_pFrame, TBSTYLE_FLAT, WS_CHILD|CBRS_ALIGN_TOP, CRect(0, 0, 0, 0), IDR_PLUGIN_1)
|| !m_wndPlugInToolBar.LoadToolBar(IDR_PLUGIN_1))
{
TRACE0("Failed to create toolbar\n");
// reset resource handle
AfxSetResourceHandle(hInstance);
return NULL;
// fail to create
}
//lose garnage pixels
m_wndPlugInToolBar.SetBarStyle(m_wndPlugInToolBar.GetBarStyle()|CBRS_BORDER_3D);
m_wndPlugInToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndPlugInToolBar.SetWindowText("TraySetup & Communication");
m_wndPlugInToolBar.EnableToolTips(TRUE);
// reset resource handle
AfxSetResourceHandle(hInstance);
retrun true
}
-Mohit
|
|
|
|
|
3 possible things:
1. Check out your registry entries for LoadBarState()/SaveBarState(). You can have problems if your trying to load a state that is invalid for the new configuration of toolbars. Just delete all the toolbar position registry entries.
2. Are you using MFC in a DLL for both the DLL and EXE projects?
3. In my code I new the CToolbar object and return a pointer to it. In yours its part of the DLL app object. Their could be a problem accessing this memory from the exe file. Create the object on the heap and return a pointer to it.
HTH
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
Hi Roger,
I am not saving Barstate in the registry...
Yes, i am using MFC for both DLL and EXE... is this creating probs???
and the third point you mentioned... might be the problem.. is it possible that this would create probs.... Since one thing i want to know...
In one other method.. i had created a button (appened a button) to the default toolbar) from the DLL... here also i did from DLL.. the button shows and works without probs...
But stillif this prob is not solved this way, then ithink i would be changing the code referring your code... creating a pointer and return it...
One more thing... so if your method works out, then do I assume that all of the Plug-Ins written for various apps like MS Office, Winamp, VS 7.0, etc do it this way... (i mean, that their main app takes care of calling CreateToolBar() method???)
I would be now trying your way, and would let you know of any probs...
Thanks a lot for your valuable time,
Regards,
Mohit
|
|
|
|
|
I want to access remote database(SQL Server) on a different Lan.I am working on ATL.How do I do it??
|
|
|
|
|
Read some documentation on ODBC and ADO. Look under Data Services in MSDN.
Michel
It is a lovely language, but it takes a very long time to say anything in it, because we do not say anything in it, unless it is worth taking a very long time to say, and to listen to.
- TreeBeard
|
|
|
|
|
And how the heck do you expect us to answer that when you don't say what DB API you're using (or even what you'd like to use)? With the information you have given so far I'd say you should go with Firebird.
|
|
|
|
|
Is the debugger in VC++ always indicating mem leaks, or is it necessary to change the settings ?
~RaGE();
|
|
|
|
|
VC++ debugger does not indicate the memory leaks.
You can use CRT libary programatically to check the memory leaks, but this is of not great help compred to third party tools like BoundsChecker, etc.
Thanks,
Ramy
|
|
|
|
|
Ramu Pulipati wrote:
VC++ debugger does not indicate the memory leaks.
Hem .. actually it does ... what I want is (surprisingly) not to know _where_ are memory leaks, but to know if _there are_ memory leaks ...
To be a little bit more clear, I have developped an API. In a test program for this API, I do not have any mem leaks detected by the debugger. But when I use some functions from this API into a more consequent mem leaks free application, then I get the memory leaks. So i suppose this __must_ be the API, and hence I´ve concluded that in the big application, project settings must have changed so that it indicates mem leaks . Is that clear or are you already (BTW is that a new emoticon ? Never saw it before ??)?
~RaGE();
|
|
|
|
|
Yes, it's a new emoticon. VC *tries* to detect memory leaks, third party products do it better.
Christian
I am completely intolerant of stupidity. Stupidity is, of course, anything that doesn't conform to my way of thinking. - Jamie Hale - 29/05/2002
Half the reason people switch away from VB is to find out what actually goes on.. and then like me they find out that they weren't quite as good as they thought - they've been nannied. - Alex, 13 June 2002
|
|
|
|
|
VC detects mem leaks by use of redirecting new and delete functions.
When u'r using API calls for allocation and such, VC debugger can't see that.
For these leaks use boundschecker and such..
|
|
|
|
|
OK. Thanx to all of you.
~RaGE();
|
|
|
|
|
I suspected that I had a memory leak or handle leak of some sort and have spent ages trying to find it. The other day I found a free 30 day demo for an app called GlowCode. It was really easy to use, you don't change your code, just attach it to your app while its running.
Anyway I found my problem in a couple of hours . I thought you might be interested, here's the link ....
http://www.glowcode.com/
Ali
|
|
|
|
|
Ouahh that app is great !
Thank you very much !!!!
~RaGE();
|
|
|
|
|
Hi
I'm just looking for the header file shldisp.h, but could not find it anywhere. MSDN didnt help, and I installed VS SP5, but it didnt contain this file. Where to get it? If somebody got, can you attach this here?
Regards,
Ravi
|
|
|
|
|
|
Help please - I have an INSERT query of the form:
INSERT INTO MyTable (Field1, Field2...) VALUES (Value1, Value2...)
into a SQL Server Database. It is failing due to invalid text in one of the Parameters.
Now, I want to report the SQL query and Parameter Values when the failure is detected to aid debugging any future issues.
But GetSQL() only returns the SELECT query - the m_strUpdateSQL contains the "INSERT ... VALUES (?, ?...)" but there is no access Function!
Also if I try to use GetFieldValue() (to try to report the parameter values) my application just dies with an exception - presumably because they are only valid for a SELECT?
Is there any way to get at the Parameter Values?
Any help from someone out there who is familiar with CRecordsets, etc. would be gratefully received.
|
|
|
|
|
I'm having trouble understanding your question.
Is the Insert generated by your code then executed in a CRecordset Open or CDatabase Execute? If so, just print it out.
Is it in a stored procedure on the SQL server? If so, You're asking the wrong people.
Once you have the statement, copy it into a SQL Server Query Analyzer window to see diagnostics and error messages.
|
|
|
|
|
You need to execute your SQL Statement with CDatabase::ExecuteSQL and get the error with CDBException
CString str = "INSERT INTO MyTable .....";
TRY
{
m_db.ExecuteSQL(str);
}
CATCH(CDBException, e)
{
AfxMessageBox(e->m_strError);
}
END_CATCH
Best Regards
Carlos Antollini.
www.wanakostudios.com
Sonork ID 100.10529 cantollini
|
|
|
|
|
You need to be more specific.
Please catch a CDBException and look at the m_strError member and what it says.
Henry Kafeman wrote:
It is failing due to invalid text in one of the Parameters.
Maybe you forgot to add the apostrophe ' like this:
INSERT INTO Table VALUES ('myvalue') and not INSERT INTO Table VALUES (myvalue)
Best regards,
Alexandru Savescu
|
|
|
|
|
Thanks for your responses so far.
I'll try to clarify - My Query is generated by the CRecordset::Update() Function.
I know why an error was occuring, but I want to build into my Release code enough Reporting to be able to diagnose any future problems.
I have a Try/Catch around the Update() call which is already reporting the SQL Error reported back by SQL Server via CDBException. What I want to do is report the actual Query and Parameters which cause a problem.
|
|
|
|