|
Just some more information...
The OLE Automation restriction is there for a reason. The idea is that if an interface supports OLE automation no external proxy code is required to marshal the calls.
I leave it to the reader to translated what I just said into English. I know for the longest time I had NO CLUE what any of that ment. (Heh, and I hope I got the statement right.)
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
|
Nish,It's also nice to use _bstr_t ,it encapsulate the BSTR
data type.It manages resource allocation and deallocation through internall calls
to SysAllocString() and SysFreeeStrnig so you don't have to add
these function to your code.It provides a number of operators that enable you to use a
_bstr_t object as easily as you would use a CString .But one thing
that isn't provide,is the & "address of" operator,so can't pass the address of
a _bstr_t to a function that expects a BSTR * .
Hope that helps.
Mazy
"So,so you think you can tell,
Heaven from Hell,
Blue skies from pain,...
How I wish,how I wish you were here." Wish You Were Here-Pink Floyd-1975
|
|
|
|
|
I am writing codes to put a view in a dialog.
Here are the code to initialize the view in a dialog:
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
CCreateContext pContext;
CWnd* pFrameWnd = this;
pContext.m_pCurrentDoc = new CMyDoc();
pContext.m_pNewViewClass = RUNTIME_CLASS(CMyView);
CMyView *pView = (CMyView *) ((CFrameWnd*)pFrameWnd)->CreateView(&pContext);
ASSERT(pView);
pView->ShowWindow(SW_NORMAL);
CRect rectWindow;
GetWindowRect(rectWindow);
ScreenToClient(rectWindow);
rectWindow.right += 15;
rectWindow.top -= 10;
pView->MoveWindow(rectWindow);
return TRUE;
}
I got two problems:
(1) If the CMyView is kind of CHtmlView and if the dialog is displayed within an MFC MDI application, when I clicked the view right after the view is displayed, I got an ASSERT in CView::OnMouseActivate(..). But if the dialog is the main window of a dialog-based MFC app, it works fine. Why?
(2) I use the following code to detect if there is memory leak:
void CMyDlgView::OnViewViewInDialog()
{
#ifdef _DEBUG
CMemoryState oldMemState, newMemState, diffMemState;
oldMemState.Checkpoint();
#endif
ShowDialog();
#ifdef _DEBUG
newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "Memory leaked!\n" );
}
#endif
}
void CMyDlgView::ShowDialog()
{
CMyDialog dlg;
dlg.DoModal();
}
if it is a CHtmlView derived view, there is memork leak; however if it is a generic CView derived view, no memory leak. Why?
|
|
|
|
|
It is this that got me thinking:
((CFrameWnd*)pFrameWnd)->CreateView(...) If I'm understading your code, pFrameWnd is a CDialog and not a CFrameWnd . My guess it that this works (when it does) due to pure chance, and it's no wonder weird things happen afterward. Maybe you can take a look at the source code of CFrameWnd::CreateView to try to determine what's going wrong.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
I have tried other method to create a view using something like:
CView *pView = pRuntimeClass->CreateObject();
pView->Create(...);
It got the same assert. However if I add (Overide) a message handler of OnMouseActive(..)of CMyView and just call CWnd::OnMouseActivate(..) within that handler, the ASSERT goes away. Odd!
|
|
|
|
|
One of the problems I've come across when using the CMemoryState items is that they tend to take an exact snapshot of memory. Good for some things, bad for others. It showed a memory leak in my code that was really just the fact that I took the snapshot before initializing an array and then comparing it to the array after it was freed and set to empty at the end of the function. The 'leak' went away if I took the snapshot after I did a memset to initialize the array instead of before. My guess is that the class initializes some structures and the difference is shown as a leak. If you use a trial version of one of the other memory checkers (BoundsChecker, Insure, etc...) then it might help determine if it's a real leak.
Good luck with the project.
|
|
|
|
|
Anonymous wrote:
My guess is that the class initializes some structures and the difference is shown as a leak. If you use a trial version of one of the other memory checkers (BoundsChecker, Insure, etc...) then it might help determine if it's a real leak.
Thanks a lot. Your argument is what I have been suspecting. I would try other memory check programs for this example. Hope you are right.
|
|
|
|
|
|
Have you included <tchar.h> ?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
|
My guess is I can't do this stuff on Win 98!!!
You can write Unicode stuff in Win98, altough you might not be able to run it (I've written Unicode things in Win95). The problem must lie elsewhere. Is TEXT also undefined?
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Joaquín M López Muñoz wrote:
The problem must lie elsewhere. Is TEXT also undefined?
Yes. I believe the problem lies elsewhere [actually I have a guess as to the "elsewhere"]
I got an error message [actually a warning] that the unicode dll could not be loaded. So for some strange reason my Win 98 does not support unicode
Nish
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
Nish [BusterBoy] wrote:
So for some strange reason my Win 98 does not support unicode
Windows 3/95/98/ME do not support unicode, Windows NT/2k/XP do.
- Matt Newman
-Sonork ID: 100.11179:BestSnowman
Frankly AOL should stick to what it does best: Fooling millions of americans into believing that it, AOL, is the web. -Paul Watson
|
|
|
|
|
MFC v6 unicode DLLs will NOT load on the 9x platforms.
If you really want to do Unicode on 9x, you can use MSLU (a.k.a. Unicows). It is a GREAT little package that MS did that thunks all the Unicode calls down to ANSI calls on 9x. We use it in our product.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Hello
I was playing around with ATL and find that when we have a function that takes a string as in or out parameters we always use BSTR*. Why don't we use just BSTR? Is it for the obvious pass by pointer reasons?
For example :-
interface INishFirst : IDispatch
{
[id(1), helpstring("method GetString")] HRESULT GetString([in] BSTR* pbstrInString, [out,retval] BSTR* pbstrOutString);
};
Could I have used BSTR there, somehow?
Nish
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
Hi Nish,
I think that if you forget the fact that BSTR is really a pointer, then you'll see the answer. If instead of BSTR you were using longs, for example, to pass an [out] parameter, it would be no good having [out, retval] long lResult, as lResult would be copied from the caller and placed on the stack. When the function exits, the caller's lResult would have the same value as it did before the call.
So, in the above example, I wouldn't bother passing in BSTR * for the [in] parameter, but you need to have BSTR * for the [out] parameter so that the caller gets the updated value when the COM method exits.
Sorry, that reads as quite confusing. Hope it helps, though.
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
|
That is true, but it's not like an ordinary (char *), because the four(?) bytes in front of the location pointed at by the BSTR contain the length of the BSTR. Because of this, I think, it's better to think of a BSTR as an encapsulated data type and not rely on it being a pointer to something. Again, I'm no expert.
What I do know, though, is that if you tried to pass a BSTR as an [out] parameter, it would not be accepted by VB (or other Automation-compatible languages). Of course, that may not be an issue for you, but you never know...
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
Thanks Derek.
Derek Waters wrote:
What I do know, though, is that if you tried to pass a BSTR as an [out] parameter, it would not be accepted by VB (or other Automation-compatible languages). Of course, that may not be an issue for you, but you never know...
It would be an issue for me. My primary intention in learning ATL is so that I can try and write some components for use from ASP.
Nish
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
Oh yeah, the marshalling for a BSTR * is probably smaller/quicker than BSTR. Maybe. I'm no expert...
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
The marshalling speed is not affected by whether you use a BSTR or a BSTR*.
When the COM object is instantiated as an INPROC_SERVER, the BSTR has one less pointer dereference, then memory is read from both types in the same way.
When the object is instantiated as a LOCAL_SERVER, or a REMOTE_SERVER, the data from both strings is completely packaged up and marshalled to the the client process. The time that it takes to dereference the extra pointer for the BSTR* is trivial compared to the process context switch or the network latency that is involved in marshallig the data.
Basically what it boils down to is the fact that you should use a normal variable type for input parameters, and pointers to the data type for output parameters.
If you use a pointer for input parameters, that is one extra check that needs to be made in order to guarentee that the pointer is valid, when this check does not have to be made when the value is input.
Because there is no pass by reference in COM, the only other way to return a value through a parameter is through a pointer.
|
|
|
|
|
Another point Nish:
[out] parameter should always be a pointer
Mazy
"So,so you think you can tell,
Heaven from Hell,
Blue skies from pain,...
How I wish,how I wish you were here." Wish You Were Here-Pink Floyd-1975
|
|
|
|
|
Hi codegurus there.
I am doing some network programming using MFC these days. I have two application, one is server, one is client. For server, I make it an un-blocking one using WSAAsyncSelect, and specify to respond to the following network event:
FD_READ | FD_WRITE | FD_ACCEPT | FD_CLOSE
At the client end, it's simple. I have three menu item, one is open_connection, one is close_connection, the other is send_receive. Here's part of my code for client:
OnConnectionClose()
{ shutdown(mysocket, SD_SEND);
closesocket(mysocket);
}
OnConnectionOpen()
{ mysocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(mysocket, (LPSOCKADDR)&saServer, sizeof(saServer));
}
OnSendReceive()
{ send(mysocket, szBuf, strlen(szBuf),0);
recv(mysocket, szBuf, sizeof(szBuf), 0);
}
And at server end, I respond to the network event like this:
OnNetWorkEvent(WPARAM wParam, LPARAM lParam)
{
switch(WSASELECTEVENT(lParam)
{
case FD_CLOSE:
closesocket(wParam);
TRACE("FD_CLOSE received\n");
break;
case FD_ACCEPT:
... ...
}
}
the problem here is: on client end, if I do "open_connection", then "close_connection", the server end will receive the FD_CLOSE event. But if I do "open_connection", "send_receive", then "close_connection", the server end will not receive the FD_CLOSE event. All other events are handled correctly. Could anybody tell me what's wrong with my coding?
Thank you all very much in advance!
|
|
|
|
|
FD_CLOSE will only be notified when there's no more data to read (you can think of it as the EOF after reading all data from a file). So it is possible that your server app is not consuming all the pending input and thus gets never notified about FD_CLOSE .
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|