|
Hi, All!
=======
What is IDISPATCH ?
What should I do with it?
How to use it?
10x
BTW: come to #CodeProject on DalNet (mIRC)
|
|
|
|
|
IDispatch is a way for pointer-challanged programming languages to call COM components. It simply gives an extra layer of abstraction to the calling procedure.
Assuming you know what interface your IDispatch you could use it in two steps:
1) Get DISPID:s for the functions you want to call with GetIDsOfNames
2) Set parameters and call Invoke with the chosen DISPID.
Example: Calling a function showWindow(BOOL show) in IDispatch idispatch
DISPID dispid;
OLECHAR* name = L"showWindow";
idispatch->GetIDsOfNames(IID_NULL, &name, 1, GetUserDefaultLCID(), &dispid);
VARIANT arg;
arg.vt = VT_BOOL;
arg.boolVal = VARIANT_TRUE;
DISPPARAMS param = {&arg, NULL, 1, 0};
idispatch->Invoke(dispid, IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, NULL, NULL, NULL);
Or you could just QueryInterface for the interface you want..
/moliate
|
|
|
|
|
Got a complex class which depends on data files opened in the constructor. Does anyone have any neat ideas about how to handle error conditions? If the files don't exist I don't want the object to be created but I can't see how to do it.
TIA
Dave Cross
|
|
|
|
|
I don't have any neat ideas, I just want to point out that the constructor is not the best place for doing a large amount of work that might fail.
Michael
|
|
|
|
|
Exceptions. Just throw an exception when your constructor fails and catch it in the code contructing the object. I think that is actually the *only* right way to do it.
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
Doing a lot of work in the constructor is generally considered bad OOP, but if you must do it than exception handling is the best technique to deal with errors, at least if this is going to be a widely distributed class.
"But, daddy, that was back in the hippie ages..." My twelve year old son - winning the argument.
"Stan, you are an intelligent guy who responds in meaningful ways" Paul Watson 16/10/01
|
|
|
|
|
IMHO doing a lot of work in ctors can't be (in general) consider bad OOP.
A design approach that works nicely with OOP and ctors is the idea of having the objects keep an invariant condition that holds for the entire lifespan of the object. This invariants help deal with the object and ease the implementation of their methods --you can think of invariants as a semantic contract with a class instance.
So, if initializing an invariant condition takes a lot of work due to the complexity of the invariant, the proper place to do that is precisely the ctor. After construction you know everything's in place, without resorting to init() methods and stuff like that. If you cannot grant that invariant on construction time, throw ing is the exact thing to do.
I would even dare to say that huge ctors (if properly backed up by meaningful semantics) provide for richer, easier to use classes.
Joaquín M López Muñoz
Télefónica, Investigación y Desarrollo
|
|
|
|
|
I'm not religious about it one way or the other. I certainly understand that one methodology will never solve every possible design problem. My personal philosophy though remains that a complex ctor made dependent upon exception handling is generally not superior to a simple "init()" call. But I am not prepared to say that it is always inferior. I have always found it very convenient to be able to return a complex object to its original default state at any point in its lifetime with an initialization function of some kind. You just have to remember that the init() cannot be virtual if you intend to use it from the ctor.
"But, daddy, that was back in the hippie ages..." My twelve year old son - winning the argument.
"Stan, you are an intelligent guy who responds in meaningful ways" Paul Watson 16/10/01
|
|
|
|
|
Effectively throwing an exception is the way to let the client knows about the error. If lot of stuff is done in the constructor, you probably also want to do some cleanup if an error occurs and in that case one of the following design may help (choose the one that best fit).
1) Uses ressource wrapper classes for ressources (like std::auto_ptr for pointers). Thus every member that allocate a ressource (memory, handle) is a wrapper.
2) Uses the pimpl idiom. The implementation class should then have a trivial constructor that may not have an error (set pointer to NULL, handle to INVALID_HANDLE_VALUE,...) and an initialisation function that do the actual initialisation.
class VClass {
private:
class VImpl;
VImpl *m_pImpl;
};
class VClass::VImpl {
public:
VImpl(); // Simple initialisation only
~VImpl(); // Release every allocated ressource
void init(); // Complex initialisation
};
VClass::VClass() {
std::auto_ptr<VImpl> pImpl = new VImpl;
pImpl->init();
m_pImpl = pImpl.release();
}
VClass::~VClass() {
delete m_pImpl;
}
3) Derive from a class that hold the ressource and do the initialisation in the derived class constructor by calling an initialisation function in the inherited class. That way if an exception is thrown from the derived class, the base class that hold the ressource will have its destructor called since it is a completly constructed object.
4) Uses wrapper class in the constructor body and at the end of the constructor body transfer the ownership from the wrapper class to the associate member of the class.
I do not like complex constructor without using one (or more) of the design above since it complexify the constructor error handling a lot (for ex. closing file that have been opened up to that point).
Note that the patterns #2 and #4 above typically allows to reduce compilation depedencies in the header file... which is often desirable when a class is complex.
Philippe Mori
|
|
|
|
|
Hello!
Could you tell me how to add the new submenu in MyMenu & how to save this submenu for future use?
|
|
|
|
|
Try using AppendMenu(...) to add the menu or InsertMenu(...) if you don`t just want to add it to the end. As for saving the menu, I don`t know how you`d do that or even why you`d want to? If you want the appended menu to appear as a popup, remember to specify the MF_POPUP flag with the (UINT)yourMenuName.m_hMenu as the menu id you want appended, followed by a caption. If you just want to add a new *ITEM* instead of a whole submenu you can use the MF_STRING with a menu command id and then what caption you want the menu item to display.
Alan.
"When I left you I was but the learner, now I am the Master" - Darth Vader
|
|
|
|
|
Hello!
Could somebody tell me how to associate some data (text) with any item in the Tree?
For example: In the left side of my dialog box - Tree, right side - Edit. When I click on any item on the Tree -- some text appears in the Edit.
How can I do it?
Thank you.
|
|
|
|
|
Here are some pointers to help you a bit:
1. When you add an entry to the tree control:
CString *p_strData = new CString;
Which dynamically allocates a new CString. Then, use the Item data part of your tree item to store this pointer:
m_MyTreeCtrk.SetItemData( hItem, (DWORD) (CString *) p_strData );
hItem is the HTREEITEM handle from when you added the tree item to the control. p_strData is cast to a DWORD to jam it into the item data. This works because a pointer is 32 bits and so is a dword.
Then, handle some treeview notifications, probably the sel_changed one, and extract the pointer from the item data:
CString *p_strData=(CString *) (DWORD) GetItemData(hItem);
then you can SetWindowText with the CString to populate your edit control. Update the data in the same way.
Remeber, it is critical that as you delete items from the tree, you first get their item data memeber back as a CString, and delete it. Otherwise you'll get a lot of memory leakage.
Hope that helps.
Jon
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
Hello chaps,
Im doing rather a complex SQL query containing temporary tables, 'GROUP BY', 'INTO', 'HAVING' and 'JOIN'. Im trying to use CRecordset but am having difficulty.
Alternatively my query could be made into a stored procedure which requires two variables, I looked at ExecuteSQL() but found it didnot return a recordset. I need to access a record set from the query.
I have managed to connect my C++ project to the correct SQL Server 7 database and are having trouble with returning a record set.
Please any comments?
Philip Shepherd
RF Design/ Software Engineer
|
|
|
|
|
This sounds similar to a problem I was having a couple of days ago.
I have a stored proc that returns a set of data. In query analyzer it worked fine, however when trying to get the data into an ADO recordset, it would come back empty.
My solution was to include a 'SET NOCOUNT ON' statement at the beginning of the stored proc. This suppresses the 'x rows affected' message.
Hope this helps in someway.
|
|
|
|
|
Use the libodbc++ library instead of the MFC database classes.
|
|
|
|
|
Use ADO, rather then the ODBC MFC CRecordset Class
See ADO samples here
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmscadocodeexamplesinvisualc.asp
|
|
|
|
|
Hi all,
I maked instance of CComboBox class (my class name is CMyCombo) !
and i wrote some new functions in new class ...
In one of functions i must put value to the Editbox in my form (dialog).
How can i do that ?
I mean putting value to editbox from my new class !
My month article: Game programming by DirectX by Lan Mader.
Please visit in: www.geocities.com/hadi_rezaie/index.html
Hadi Rezaie
|
|
|
|
|
Hadi_Rezaie wrote:
I maked instance of CComboBox class (my class name is CMyCombo) !
and i wrote some new functions in new class ...
In one of functions i must put value to the Editbox in my form (dialog).
How can i do that ?
I mean putting value to editbox from my new class !
Doing this will mean your new Combo will not be reusable, which makes it a bad design. However, all you do is ( assuming your Editbox is a member variable called m_Edit, m_szText is a member variable containing the text to put into it, and your class is called CHadiDlg )
CHadiDlg * pDlg = dynamic_cast<CHaduDlg*>(GetParent());
ASSERT(pDlg);
pDlg->m_Edit.SetWindowText(m_szText);
Christian
After all, there's nothing wrong with an elite as long as I'm allowed to be part of it!! - Mike Burston Oct 23, 2001
Sonork ID 100.10002:MeanManOzI live in Bob's HungOut now
|
|
|
|
|
Hi,
I am developing an Aplication to watch/manage my IDS Nodes. It runs fine when I run in Release mode. Once I go to Debug I get the Assertion.
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
Any help appreciated...
Thanks in advance,
Dan
|
|
|
|
|
Where is the assert that's failing. An assert means you have a bug in your code; look for comments at the assert to tell you what it's checking for.
--Mike--
http://home.inreach.com/mdunn/
While I can't be correct on all matters, I can make the reassuring claim that where I am inaccurate, I am at least definitively inaccurate.
your with and
Sonork - 100.10414 AcidHelm
|
|
|
|
|
I sent you the Assertion I am getting in a seperate mail.
It is failing on...(BTW, this is a SDI Application)
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
This doesn't mean it is not my code, but it won't let me debug to find the Assertion...any ideas??
Thanks in advance,
Dan
|
|
|
|
|
Click Retry when you get the assert-failed message box to drop into the debugger.
--Mike--
http://home.inreach.com/mdunn/
While I can't be correct on all matters, I can make the reassuring claim that where I am inaccurate, I am at least definitively inaccurate.
your with and
Sonork - 100.10414 AcidHelm
|
|
|
|
|
It has arrived to me a short time ago. The program crashed at the return of a function. I only checked the "link incrementaly" option in debug mode. If it works in release mode...your code is probably not the probleme.
|
|
|
|
|
In the registry is in HKEY_CURRENT_USER/Network
path, where some(!) network drive UNC paths can
be found. Now I wonder where are the rest???
I am trying to make a program that will show the
paths. I have tried it on several computers, and
I have found that not all the network drives are
listed in the registry.
How could I read the UNC path for ALL network drives?
API functions for that??
|
|
|
|