|
I don't know if you have noticed[^] but SysAllocString is part of the COM library (you need to link to oleaut32.lib if you use it).
The returned type is a BSTR – a string type used by COM – rather than a WCHAR *. The differences are:
- BSTRs are allocated using the COM allocator, so they can passed to another process (and deallocated by another process). This is why you should use SysFreeString rather than delete or free.
- BSTRs have a length prefix (besides having null terminator).
The length is kept (as a UINT) in the memory location just before the first character.
The BSTR type is actually defined as a WCHAR *, pointing to the first character (just like a regular LPWSTR), so you can use BSTRs wherever you can use LPWSTRs. Just remember that you should use SysFreeString to deallocate it.
So, a regular string looks in memory like this:
S o m e [space] t e x t [null]
53 00 6f 00 6d 00 65 00 20 00 74 00 65 00 78 00 74 00 00
whereas a BSTR looks like this
string length S o m e [space] t e x t [null]
09 00 00 00 53 00 6f 00 6d 00 65 00 20 00 74 00 65 00 78 00 74 00 00
Hope this clears things up a little bit.
See also this page[^].
Florin Crişan
|
|
|
|
|
Cool Florin!
I have a further question, you mentioned below,
Florin Crisan wrote: so they can passed to another process (and deallocated by another process).
I do not quite understand what do you mean passing to another process? In my limited knowledge, I only developed in-process server COM (.DLL) before and I have never met with situation that I need to pass something to another process (in-process server COM DLL will be loaded by another process).
It is appreciated if you could provide more information about what do you mean passing the BSTR value to another process.
have a good weekend,
George
|
|
|
|
|
I'll reply to that...
If you used an out of process COM (either just in an exe, or on another machine), windows does the heavy lifting of transferring the parameters to your COM interface functions for you.
BSTR is a) Easy for it to marshall (moving about) and (b) is the string type originally used by VB, so your COM object can be used by VB programs, VBScript, etc. Lots more than clean nice pure C++ programs.
Iain.
|
|
|
|
|
Thanks Iain,
As you mentioned marshall, it is one of the things I want to learn in the past, but missed some good tutorials. I have C++ native unmanaged COM (in-process server) development experience, could you recommend some learning materials about marshall please?
regards,
George
|
|
|
|
|
Sorry, I've just been picking this stuff up as I go.
I would recommend Michael Dunn's series on shell extensions for a good (free) start.
Iain.
|
|
|
|
|
Hi Iain,
What do you mean *Michael Dunn's series on shell extensions*? Could you provide an URL please?
regards,
George
|
|
|
|
|
Try using the author search - they'll be pretty obvious!
Iain.
|
|
|
|
|
SysAllocString() creates a BSTR (BASIC STRing), which is the primary means for passing strings between COM objects. Memory for the string is managed by COM. Depending upon the usage, you may need to call SysFreeString() to release the memory allocated to the string when you're finished with it.
If you are using COM, then you will probably need to use BSTR 's.
There is no performance or other advantage to using them otherwise. If you just need simple wide character strings, use wchar_t strings.
Software Zen: delete this;
|
|
|
|
|
Thanks Gary,
I have also done some self-study, here in MSDN
http://msdn2.microsoft.com/en-us/library/ms221069.aspx
It is mentioned,
BSTRs are allocated using COM memory allocation functions. This allows them
to be returned from methods without concern for memory allocation.
I do not quite understand what does it mean? No need to take care of memory
allocation? We still need to call SysFreeString manually.
regards,
George
|
|
|
|
|
Hello,
Can we use DoModal like this:
<br />
CMyAlert *alert = new CMYAlert;<br />
alert->Create(CMYAlert::IDD,this);<br />
<br />
<br />
if (alert->DoModal()==IDOK)<br />
{<br />
message("IDOK is clicked")<br />
}<br />
I want to know when IDOK is clicked On CMyAlert,
Is there another way to know it?
thanks
|
|
|
|
|
Gofur Halmurat wrote: I want to know when IDOK is clicked On CMyAlert,
The CMyAlert dialog will have to notify the parent window that the OK button was clicked. either by passing a pointer to the parent to the dialog? or from the dialog, send a private message to the parent window saying the OK was clicked.
What is your intention ?
Do you want to have the dialog dismissed when the user clicks on Ok ?
|
|
|
|
|
Hello,
My parent window has a button, if i click the button the CMyAlert appears, and there is a button on CMyAlert, when i click the button on CMyAlert, Some changes will have to be done on parent window. How can i implement this?
either by passing a pointer to the parent to the dialog? or from the dialog, send a private message to the parent window saying the OK was clicked.
How can i implement this option? can u show me with examples?
thanks
|
|
|
|
|
are you wanting a modeless dialog by any chances ?
if not, then why don't you do the job when the modal dialog is closed ?
|
|
|
|
|
Hello,
yes, i want a modeless dialog by any changes
|
|
|
|
|
so you mustn't use DoModal() (which, as its name states, creates a Modal Dialog).
use Create() method to create it.
to have the possibility to modify the window which spamn it, you must give it a pointer to its parent (commonly, this ) as a constructor parameter
also read This[^] good article about modeless dialogs.
|
|
|
|
|
Thanks, that was what i was looking for. it helped me alot
|
|
|
|
|
And no, you can't use Create() and DoModal() - you use one or the other,
depending on whether you want a modal or a modeless dialog.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
No. By calling the Create function for your alert dialog, you've made it a modeless dialog. Calling DoModal() in this case will not work correctly.
There are two solutions here. One, use the alert dialog modally:
CMyAlert *alert = new CMyAlert;
if (alert->DoModal() == IDOK) {
message("IDOK is clicked");
}
delete alert; The second is to use your alert dialog as a modeless dialog, and have it send a user-defined message to the parent when the OK button is clicked, which is more complicated:
#define WM_MyAlertMessage (WM_USER + 1)
void CMyAlert::OnOK()
{
CWnd *parent = GetParent();
if (parent != NULL) {
parent->SendMessage(WM_MyAlertMessage,0,0);
}
}
BEGIN_MESSAGE_MAP(CMyParentWindow,CDialog)
ON_MESSAGE(WM_MyAlertMessage,OnMyAlertMessage)
END_MESSAGE_MAP()
LRESULT CMyParentWindow::OnMyAlertMessage(WPARAM ,LPARAM )
{
message("IDOK is clicked");
return (LRESULT)0;
}
Software Zen: delete this;
|
|
|
|
|
Hello everyone,
I am surprised to see that the value of sign ' is the same as \'. So, there is no need to add sign \ before sign '? In my past knowledge of sign ', we always need to add sign \ before sign '. Any comments?
Here is my simple program to test.
<br />
<br />
int main (int argc, char** argv)<br />
{<br />
char* p1 = "Hello \'World\'";<br />
char* p2 = "Hello 'World'";<br />
int result = 0;<br />
<br />
result = strcmp(p1, p2);<br />
<br />
return 0;<br />
}<br />
thanks in advance,
George
|
|
|
|
|
My friend, is quite obvious that ' is different from \' (just kidding).
Talking a bit seriously, you need such an escape sequence (that is symbol \' ) in circumstances like the following:
char c = '\'';
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
Hi CPallini,
Actually I am also confused when I tried that,
"Hello 'World'" is the same as "Hello \'World\'". I have also tried your sample. Now I am more confused...
1. What is the rule when we should use \' or single ' ?
2. When there is no differences between \' and '? (like my Hello 'World' sample)
regards,
George
|
|
|
|
|
Hi.
You use single ' inside a string delimited by " characters
i.e.
char* p2 = "Hello 'World'";
You use the \' when iusing it as a single character that need to be quoted within ' characters
i.e.
char p1 = '\'';
Habetis bona deum
|
|
|
|
|
Good reply, thanks DoomedOne!
regards,
George
|
|
|
|
|
as C Pallini stated, you need to use \' only when the compiler can get confused.
technically, \' is the same ascii code as the character ' .
just same as \" is the same ascii code as the character " .
so, in brief, ben you use ' in a string (so, rounded with " s), you don't need to use the escapment char ( \ ).
when you use " as a single char, no need either to use \ .
some examples:
"Hello \'World\'" is the same as "Hello 'World'" .
"Hello "World"" is forbidden because the second " char is understood as the end of the string.
here, you MUST write: "Hello \"World\""
'"' is the ascii code of the " character.
''' is forbidden. here again, the second ' char is understood as the end of the character specification.
You MUST write: '\'' .
get it now ?
subsidiary question: please, for god' sake, in what school level are you, and how old are you ? i'm not judging you, i'm questionning myself.
|
|
|
|
|
Cool toxcct!
I must save your reply to somewhere.
regards,
George
|
|
|
|