|
>>SO that someone can figure it out
No
Code:
void __stdcall CAddon::OnOptionsAddPages(IDispatch* Ctrl)<br />
{<br />
try{<br />
CComQIPtr<Outlook::PropertyPages> spPages(Ctrl);<br />
ATLASSERT(spPages);<br />
CComVariant varProgId(OLESTR("AtlAddon.PropPage"));<br />
CComBSTR bstrTitle(OLESTR("eTopping ATL addon settings"));<br />
HRESULT hr = spPages->Add((_variant_t)varProgId,(_bstr_t)bstrTitle);<br />
}<br />
catch(_com_error &e){<br />
CString szErr;<br />
szErr.Format(_T("[CAddon::OnOptionPageAdd]: COM exception: %s; SOURCE = %s\r\n"), e.ErrorMessage(),<br />
e.Source());<br />
pLogger.Loggit(szErr.GetBuffer());<br />
}<br />
}<br />
|
|
|
|
|
Hello, I have the same problem. ¿Can you tell me how do you resolve the problem?
|
|
|
|
|
Hi,
I'm trying to create an extended label control that will be used within Excel. It is ATL/WTL and subclasses the CStatic control.
My problem is that when the control gets added to a sheet using ActiveSheet.OLEObjects.Add it always seems to appear in design mode - ie. not activated. If I toggle design-mode the control then displays correctly.
Having debugged I notice that OnCreate does not get called until I toggle design-mode.. OnDraw does get called but I require a window handle which is not available at this point..
Am I missing some activation property/method or should I be creating my own window when I realise that one does not exist?
Thanks!
|
|
|
|
|
http://img11.imageshack.us/my.php?image=nicectrl8rq.jpg[^]
I love this control, and i really would need something like it to display variable properties for objects. Anyone know how to make one? Seems to be somekind of combo between combo box and editbox in the left column. Anyone know if anyone have done anything similiar and provided sample source somewhere? Im using wtl btw.
Thanks in advance!
|
|
|
|
|
Hi, I've written (using C++ VS6) a very simple ATL COM used by asp pages. The
COM has a static global variable g_counter of long type; then the COM exposes
an Object Pluto, with a method "Increment_g_Counter" that increments the
global variable g_counter and a property get_G_Counter that retrieves the
value of g_counter.
The question is: why, using OS W2k3 and IIS6 (running in iis 5.0 isolation
mode), after a few minutes, if no clients call the asp page, the g_counter
values is 0?
IIS6 seems to unload the atl com dll (the ExitInstance Method of the
CTestasp_comApp is called) after a few minutes; I say "seems" because if I
try to copy the com dll, the system tells me "the source or the destination
file may be in use".
I think that this behavior is due to the garbage collector of IIS6.
This is the com sample code:
CComModule _Module;
static long g_counter = 0;
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Pluto, CPluto)
END_OBJECT_MAP()
class CTestasp_comApp : public CWinApp
{
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTestasp_comApp)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL
//{{AFX_MSG(CTestasp_comApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CTestasp_comApp, CWinApp)
//{{AFX_MSG_MAP(CTestasp_comApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CTestasp_comApp theApp;
BOOL CTestasp_comApp::InitInstance()
{
_Module.Init(ObjectMap, m_hInstance, &LIBID_TESTASP_COMLib);
FILE *fptrace = fopen( "f:\\giffile\\asptrace.txt", "a" );
if ( fptrace != NULL )
{
fprintf( fptrace, "InitInstance g_counter=%d\n", g_counter );
fclose( fptrace );
}
return CWinApp::InitInstance();
}
int CTestasp_comApp::ExitInstance()
{
FILE *fptrace = fopen( "f:\\giffile\\asptrace.txt", "a" );
if ( fptrace != NULL )
{
fprintf( fptrace, "ExitInstance g_counter=%d\n", g_counter );
fclose( fptrace );
}
_Module.Term();
return CWinApp::ExitInstance();
}
This the object code
class ATL_NO_VTABLE CPluto :
public CComObjectRootEx<ccomsinglethreadmodel>,
public CComCoClass<cpluto, &clsid_pluto="">,
public IDispatchImpl<ipluto, &iid_ipluto,="" &libid_testasp_comlib="">
{
public :
CPluto()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_PLUTO)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CPluto)
COM_INTERFACE_ENTRY(IPluto)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IPluto
public:
STDMETHOD(get_G_Counter)(/*[out, retval]*/ long *pVal);
STDMETHOD(Increment_g_Counter)(/*[out,retval]*/int *ok);
};
#endif //__PLUTO_H_
.cpp
STDMETHODIMP CPluto::Increment_g_Counter(int *ok)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
CSingleLock lock( &gLockManager, TRUE );
g_counter++;
lock.Unlock();
return S_OK;
}
STDMETHODIMP CPluto::get_G_Counter(long *pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
*pVal = g_counter;
return S_OK;
}
This is the asp code
Dim value
Dim counter_object
Set counter_object = Server.CreateObject( "testasp_com.Pluto")
counter_object.Increment_g_Counter
value = counter_object.G_Counter
Response.Write "Value is" & value & " "
Set counter_object = Nothing
I need a behavior like iis5 that keeps COM global variables alive until an
iisreset command is sent.
Thanks for any help.
Max
Massimo B.
|
|
|
|
|
Periodically, IIS is calling CoFreeUnusedLibraries() to unload any in-proc servers that have a refcount of 0. This is standard good behavior for an app that uses COM objects.
--Mike--
Visual C++ MVP
LINKS~! Ericahist | NEW!! PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
"That probably would've sounded more commanding if I wasn't wearing my yummy sushi pajamas."
-- Buffy
|
|
|
|
|
Ok; this may be good for many applications; but suppose that (this is my real case) instead of a dummy variable long g_counter, you have a pointer to an object, (a map server) that "must" be always alive and "must" be persistent because it must remember and know its state; such behavior is not good.
So do you know if there is some way to disable this IIS's behavior?
Thanks a lot.
Max
Massimo B.
|
|
|
|
|
MaX B. wrote: know its state
Persist its state somewhere: session or application objects, database, etc.
|
|
|
|
|
Hello all, I have already posted this in the SQL board, but I didn't get any answer. I thought that perhaps this section would be more appropriate for this request. In any case, this is just to say that I am not spamming ...
I have been looking everywhere for a solution to this, but I couldn't find it.
I am trying to access a (generic) database using OLEDB Consumer Templates (of which I have little experience) in a WTL project (VC 2003, WTL 7.5).
Ok, the problem is that when I open a CCommand object passing a DBPropSet structure I get no rows in return.
Let me try to explain with the code..
With the following code everything works fine. I get columns and rows correctly (I removed a lot of stuff such as error handling, to simplify). The code it’s more or less the same used in the MSDN sample DBViewer:
<code>
CCommand<CManualAccessor> oCmd;
oCmd.Open(m_session, sSQL, NULL, &nRows, DBGUID_DEFAULT, FALSE)
if (oCmd.m_spRowset == NULL)
{
//ERROR STUFF
}
if (oCmd.GetColumnInfo(&ulColumns, &pColumnInfo, &pStrings) != S_OK)
ThrowOleDBError(oCmd.m_spRowset, IID_IColumnsInfo);
struct MYBIND* pBind = new MYBIND[ulColumns];
oCmd.CreateAccessor(ulColumns, &pBind[0], sizeof(MYBIND)*ulColumns);
for (ULONG l = 0; l < ulColumns; l++)
oCmd.AddBindEntry(l + 1, DBTYPE_STR, sizeof(TCHAR)*255, &pBind[l].szValue, NULL, &pBind[l].dwStatus);
oCmd.Bind();
ULONG ulFields = oCmd.GetColumnCount();
while(oCmd.MoveNext() == S_OK)
{
for (ULONG j = 1; j <= ulFields; j++)
{
lpszString = pBind[j-1].szValue;
// PRINTING STUFF
}
}
</code>
Now, if I add properties to the command using this:
<code>
CDBPropSet pset( DBPROPSET_ROWSET );
pset.AddProperty(DBPROP_IRowsetView, true);
pset.AddProperty(DBPROP_IRowsetScroll, true);
pset.AddProperty(DBPROP_IRowsetChange, true);
pset.AddProperty(DBPROP_UPDATABILITY,
DBPROPVAL_UP_INSERT | DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_DELETE);
pset.AddProperty( DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL );
pset.AddProperty( DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL );
/*…*/
oCmd.Open(m_session, sSQL, &pset, &nRows, DBGUID_DEFAULT, FALSE, 1)
/*…*/
</code>
I get the columns shifted right (like if there is an empty column before all the others), and no records.
The m_spRowset member however it’s not null, as I check for it after the call to Open()
Can you please help me out, or at least tell me why this happens?
Thank you very much!
Guybrush Threepwood
|
|
|
|
|
Wow, is it really possible that nobody has an answer for this?
Sorry sorry, I don't mean to be arrogant... It's just that I was able to find two more requests like mine looking through forums and the usenet, and nobody got an answer either.
Is it just a very stupid error on my part? Is it a bug in the templates?
|
|
|
|
|
Hi
I have a ICopyHook extension DLL. But this DLL is coming to effect only when i restart my explorer i.e, by lkilling the explorer.exe. If i register the DLL, i will have to kill the explorer.exe to make it work. Is there any way by which i can make the DLL work wihtout restarting the explorer.
|
|
|
|
|
I have to create a Transparent static text in an ATL Composite control dialog, So that the background image must see from top.
Please help!
ANil
|
|
|
|
|
Add a message handler like list to the dialog:
MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColorStatic)
Add the handler:
LRESULT OnCtlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)<br />
{<br />
HWND hEdit = GetDlgItem(IDC_STATIC1);<br />
if ( hEdit == reinterpret_cast<LRESULT>(lParam) )<br />
{<br />
HDC hDC = reinterpret_cast<HDC>(wParam);<br />
SetBkMode(hDC, TRANSPARENT);<br />
return reinterpret_cast<LRESULT>(GetStockObject(HOLLOW_BRUSH));<br />
}<br />
<br />
return 0;<br />
}<br />
Steve
|
|
|
|
|
I did as this, but still it Static text is not transparent. Then I check in Debug and found that the control is not enetering in OnCtlColorStatic function.
PS: am subclassing the Dialog to display background image
|
|
|
|
|
The WM_CTLCOLORSTATIC is sent to the parent of the static text control - Make sure you're handling it in the dialog and not the control itself. To handle it in the control you need to use message reflection, don't worry about this for now.
Steve
|
|
|
|
|
Yes, I am handling WM_CTLCOLORSTATIC in dialog itself. But there is no change in behaviour of static text. How to proceed now?
|
|
|
|
|
I'm not sure what could be going wrong - Perhaps if you post some of your code...
Steve
|
|
|
|
|
I have message handler
MESSAGE_HANDLER(WM_CTLCOLORSTATIC,OnCtlColorStatic)
and handler function like
LRESULT OnCtlColorStatic(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HDC hdcStaic = (HDC) wParam; // handle to display context
HWND hwndStaic = (HWND) lParam; // handle to static control
HWND hEdit = GetDlgItem(IDC_STATIC_MESSAGE_BOARD);
if ( hEdit == hwndStaic )
{
HDC hDC = reinterpret_cast<hdc>(wParam);
SetBkMode(hdcStaic, TRANSPARENT);
SetTextColor( hdcStaic, RGB( 0, 0, 255 ) );
return reinterpret_cast<lresult>(GetStockObject(HOLLOW_BRUSH));
}
}
and I did set background image by subclassing the dialog where the Static text placed.
|
|
|
|
|
You got me....This is almost exactly what I tried and it worked fine.
Steve
|
|
|
|
|
I have some code like this in OnInitDialog() to set background image, Does it causing the problem?
m_PictureWindow.SubclassWindow(m_hWnd);
m_PictureWindow.m_nMessageHandler = CPictureWindow::BackGroundPaint;
m_PictureWindow.Load("D:\\image.bmp");
Did there is a Background image for your dialog when you tried?
|
|
|
|
|
Try reversing the tab order. In MSVC 6:
- Select "Layout->Tab order".
- Click on all the control from the highest number to the lowest number.
This is just a hunch.
Steve
|
|
|
|
|
Still no change: Thanks for your suggestions. Lets start again a break!!!
Steve,
How I add a windows media player control to my ATL dialog. I can't add using wizard, since it not support in ATL. Then how i get the pointer to operate the control like set the movie file, start video and stop video etc etc....
|
|
|
|
|
1. Go to the dialog editor.
2. Right click on the dialog and select "Insert ActiveX Control...".
3. Select the ActiveX control you want. I selected "Windows MEdia Player", it was last in the list.
4. Press "OK.
5. Right click on the control and select "Properties".
6. Set the properties.
Try that for a start.
Steve
|
|
|
|
|
Done already, How I identify & get the interface from the control
for example, A brwser control use <iwebbrowser2> & we can get pointer "Navigate" to WebBrowser control. Like this...
CAxWindow wndIE = GetDlgItem(IDC_OCX1);
CComPtr<iwebbrowser2> pWB2;
HRESULT hr;
hr = wndIE.QueryControl ( &pWB2 );
if ( pWB2 )
{
CComVariant v; // empty variant
pWB2->Navigate ( CComBSTR("http://www.codeproject.com/"),&v, &v, &v, &v);
}
So in case of windows media player, what must be given as "IWebBrowser2". I need interface to play, stop, pause video
Please advise I am just new comer to COM interfaces
|
|
|
|
|
There are a number of ways. In the case of the WebBrowser all the files you need already come with the compiler and it's just a matter of including them. I believe the Media Player has an SDK that will the header files you need. Alternatively you can use #import . Follow these steps to use #import :
1. Load up the "OLE View" tool that comes with Visual Studio.
2. Open up "Object Classes->Grouped by Component Category->Contols".
3. Find control in question.
4. Select it.
5. In the right pane under the "Registry" tab find the Type library location. For me it looked like this: "win32 = C:\WINDOWS\System32\wmp.dll".
6. Add #import "<TypeLibrary>" to the dialog - Where <TypeLibrary> is the path to the type library. So for me I add #import C:\WINDOWS\System32\wmp.dll"
This will generate the files you need - Look for .TLH and .TLI files in your output directory, these are what was generated by #import (when you compile).
In OLE View you can right click on a component and select "View Type Information" to view the components interface.
Then you use the control with code like this:
WMPLib::IWMPPlayer4Ptr spWMP4;<br />
HRESULT hr = GetDlgControl(IDC_OCX1, __uuidof(spWMP4), (void**)&spWMP4);<br />
if ( SUCCEEDED(hr) )<br />
{<br />
spWMP4->SOME_FUNCTION();<br />
}
That's the basic idea. I don't know how to drive the Media player control so my example doesn't do much.
Steve
|
|
|
|
|