|
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
|
|
|
|
|
hi,
I am using the function ConvertResourceStringIdToLptstr() to assign the value of the TV_INSERTSTRUCT's pszText for the creation/initialization of a TreeCtrl. (or) to convert the 'resource string' into a pointer to a character string.
<br />
LPTSTR COperDialog::ConvertResourceStringIdToLptstr(UINT nResString)<br />
{<br />
CString strLoad;<br />
strLoad.LoadString(nResString);<br />
LPTSTR lpsz = new TCHAR[strLoad.GetLength()+1];<br />
CHECK_FOR_NULL(lpsz)<br />
_tcscpy(lpsz,strLoad);<br />
return lpsz;<br />
}<br />
And the fuction is used in:
<br />
void COperDialog::AddProjectRootItem()<br />
{<br />
TV_INSERTSTRUCT curTreeItem;<br />
<br />
curTreeItem.hParent =TVI_ROOT ;<br />
curTreeItem.hInsertAfter = TVI_ROOT ;<br />
curTreeItem.item.iImage = 0;<br />
curTreeItem.item.iSelectedImage = 0;<br />
<br />
curTreeItem.item.pszText = ConvertResourceStringIdToLptstr(IDS_PROJECT);<br />
curTreeItem.item.cchTextMax=15;<br />
<br />
curTreeItem.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;<br />
<br />
htrProjectRoot = m_Edit->InsertItem(&curTreeItem); <br />
<br />
}<br />
In this situation i am getting memory leaks in ConvertResourceStringIdToLptstr().
So to avoid that where should i insert the delete[]? If i use it inside the function - ConvertResourceStringIdToLptstr() i am not able to get the string displayed!
Kindly give sugesstions!!
Priya Sundar
|
|
|
|
|
You can use the pointer as member or global variable, fill it, use it and when you dont need it anymore... use delete. That way you will have the control about the pointer along the whole class / project.
LPSTR pMyLpstr;
.
pMyLpstr = NULL;
.
LPTSTR COperDialog::ConvertResourceStringIdToLptstr(UINT nResString)
{
CString strLoad;
strLoad.LoadString(nResString);
pMyLpstr = new TCHAR[strLoad.GetLength()+1];
CHECK_FOR_NULL(pMyLpstr)
_tcscpy(pMyLpstr,strLoad);
return pMyLpstr;
}
.
void COperDialog::AddProjectRootItem()
{
TV_INSERTSTRUCT curTreeItem;
curTreeItem.hParent =TVI_ROOT ;
curTreeItem.hInsertAfter = TVI_ROOT ;
curTreeItem.item.iImage = 0;
curTreeItem.item.iSelectedImage = 0;
curTreeItem.item.pszText = ConvertResourceStringIdToLptstr(IDS_PROJECT);
delete [] pMyLpstr;
pMyLpstr = NULL;
curTreeItem.item.cchTextMax=15;
curTreeItem.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
htrProjectRoot = m_Edit->InsertItem(&curTreeItem);
}
.
delete [] pMyLpstr;
pMyLpstr = NULL;
Hope it helps
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
“The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet.” - Michael A. Jackson
|
|
|
|
|
That way you have to be very careful.
I think it is an hazardous design.
Probably it would be better if both memory allocation and deallocation are delegated to the caller (e.g. the standard behaviour of Windows API).
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.
|
|
|
|