|
Thanks but how can i retrieve through programing?
|
|
|
|
|
By picking one of the links and following directions?
I just hit google with this text: "c++ retrieve blackberry imei[^]"
Heavens knows what you'll find...
|
|
|
|
|
Hello everyone,
I would like to hook OleGetClipboard to return a custom IDataObject.
Injecting my code in the target application and hooking the function is quite easy and works pretty well. However, things get messy after the code of the function has been executed (app crash after a few seconds).
Here is the code of the MyOleGetClipboard function:
HRESULT MyOleGetClipboard(LPDATAOBJECT *ppDataObj)
{
FORMATETC f = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM s = { TYMED_HGLOBAL, { 0 }, 0 };
s.hGlobal = GetFileToPaste(); // Returns the handle to the DROPFILES structure (memory allocated with GlobalAlloc)
*ppDataObj = new MyDataObject(&f, &s, 1);
return (*ppDataObject) ? S_OK : E_OUTOFMEMORY;
}
The target application calls the methods from the returned object successfully, but I suspect some memory-related problem. For instance, the following code will also lead to a crash after a few seconds:
struct CFoo
{
CFoo()
{
m_i = new int[512];
}
~CFoo()
{
delete [] m_i;
}
int *m_i;
};
HRESULT MyOleGetClipboard(LPDATAOBJECT *ppDataObj)
{
CFoo *f = new CFoo();
delete f;
return fpOleGetClipboard(ppDataObj); // Call the original implementation
}
Do you have any idea on how I should deal with this?
Any help or hint would be greatly appreciated.
Thank you!
|
|
|
|
|
Does it happen also if you do a small test app of your own and invoke your hooked procedure from that?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
No, it works fine when called from a test app of my own
|
|
|
|
|
I'm just guessing here too but try allocating/freeing memory differently, like using CoTaskMemAlloc[^] and CoTaskMemFree[^], or using the IMalloc[^]. IF you need constructors to run, then use placement new after allocating the memory, however, if your object also allocates things dynamically along the way, like your CFoo constructor does, you might need to modify that also. As said, i might be completely off the track here...
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
I overloaded the new and delete operators to use the functions you mentioned, but it does not solve the problem unfortunately.
void * MyDataObject::operator new(size_t n)
{
return CoTaskMemAlloc(n);
}
void MyDataObject::operator delete(void *p)
{
CoTaskMemFree(p);
}
I'm getting really puzzled.
|
|
|
|
|
And in your CFoo example, if you don't perform any new-delete, just call the original method, does it work?
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Yes it does. It also works with MyDataObject as long as I do not return the pointer to the caller.
I've done some more tests and I'm completely lost:
// Works fine
HRESULT MyOleGetClipboard(LPDATAOBJECT *ppDataObj)
{
return fpOleGetClipboard(ppDataObj); // Call the original function
}
// Will lead to a crash after a few seconds
HRESULT MyOleGetClipboard(LPDATAOBJECT *ppDataObj)
{
*ppDataObj = NULL;
return fpOleGetClipboard(ppDataObj);
}
// Will lead to a crash after a few seconds
HRESULT MyOleGetClipboard(LPDATAOBJECT *ppDataObj)
{
HRESULT hr = fpOleGetClipboard(ppDataObj);
OutputDebugString(L"After fpOleGetClipboard");
return hr;
}
|
|
|
|
|
Might be a calling-convention problem, try adding __stdcall or somesuch, am not sure by heart, like this:
HRESULT __stdcall MyOleGetClipboard(LPDATAOBJECT *ppDataObj)
{
...
} and see if it changes anything. Might try with __cdecl too if the __stdcall doesn't work.
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
It's working! You're a genius.
The function declaration on MSDN is actually different from the declaration in the header files, calling convention has to be __stdcall (which makes sense as this is some COM related stuff)!
Thanks so much for your help!
|
|
|
|
|
Yourwelcome, i'm glad it worked out!
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Hi everyone, I would like to know if the header file <process.h> is a Windows header file or part of the ANSI standard. If it is Windows specific header, then how will I write an application that will create threads when portability is of much concern. Thanks in advance.
|
|
|
|
|
|
«_Superman_» wrote: It is a standard C header file
I guess you completely missed the following part of the Wikipedia article: "Neither the header file nor the functions are defined by either the ANSI/ISO C standard or by POSIX"
|
|
|
|
|
It's not a standard header, it tends to be Microsoft C and it's descendents and workalikes that implement it.
So if you want to create a portable threading application then get a portable library. Your options for this include:
- Use C++0x. Unfortunately a complete implementation of this on all the platforms you want us unlikely to be supported soon. VC++ 2010 for example doesn't have the threads library in it
- Use Boost - this is a good choice as it's largely upwards compatible with the upcoming C++ standard and is maintained by Anthony Williams one of the main test implementers of the new standard
- Use some other portable library, e.g. find something like pthreads for windows and use them on all your platforms. The problem is that pthreads is pretty low level - it's really one of the assembly languages of concurrent programming
Out of those I'd go with boost as the code you write today will probably work for the next 5 years and will be fairly easy to port to whatever C++0x compilers we've got then.
Cheers,
Ash
|
|
|
|
|
In addition to what Ash said, if you are going to write a widowed application and you want it to be cross-platform, you could have a look to some cross-platform GUI library; a very good one is the Qt[^]: it has lots of classes and functionalities for GUI programming and not only (threading, XML, scripting, etc.)
|
|
|
|
|
I can only recommend boost.thread, for following reasons:
1. well documented + a lot of further resources, comments, published user experiences
2. actively maintained and extended
3. ..and in large parts compatible with c++0x
It even cooperates well (although care has to be taken) with e.g. .NET or Java multi-threading, as shortly sketched in the C++/CLI discussion thread.
|
|
|
|
|
the classwizard only allow you to handle the COMMAND, I want to implement the number wrap-around and have to handle the VSCROLL signal, how is that accomplished from the ribbon control CMFCRibbonEdit?
|
|
|
|
|
Hi all, I'm finding it difficult to assign a function that is a member of a class to a pointer to a function. I have a member function declared in a class as
bool FileMenu(void)
Then I have declared a pointer to a function as:
bool (*ptrLastMenu)(void)
But the assignment produces errors, and I don't know how to do this in C++. I don't know if it is different from the way the assignment is done in C which I am used to. Please help.
|
|
|
|
|
what have you tried? what are the symptoms?
wouldn't it just be ptrLastMenu=FileMenu; ?
|
|
|
|
|
class C1
{
void fx() { }
typedef void (C1::*memberFnPtr)();
void f2()
{
memberFnPtr g;
g = &C1::fx;
(this->*g)();
}
};
See: http://www.parashift.com/c++-faq-lite/pointers-to-members.html[^]
Use with care, because they (usually) mean that there is something about your design that you haven't thought through properly. I can't think of any situation right now where you can't use polymorphism to solve the same problem in code that you own. I haven't encountered any member function pointers in my job yet.
|
|
|
|
|
Member function pointers are really handy when you want to call the same member function on every element of a collection. It's either that or write a shim functor to do the call for you. So instead of:
class functor
{
public:
void operator()( object &obj )
{
obj.A();
}
};
std::for_each( data.begin(), data.end(), functor() );
you can use:
std::for_each( data.begin(), data.end(), std::mem_fun_ref( &object::A ) );
The first form is a real pain in the neck before C++0x as you can't define a local class or use a lamda. Your functor has to be defined "somewhere else" which can lead to a bit of flow interruption when you're reading code (for me anyway, your experience probably differs).
Cheers,
Ash
PS: Pedants please note my argument may not apply if...
- I'm not using a pointer, just taking the address of a member function
- I'm using someone else's (i.e. the standard library's)
|
|
|
|
|
I agree mostly. But I have to comment on the "flow interruption"
std::for_each( data.begin(), data.end(), increase_by_one() );
does not interrupt my reading as does this
std::for_each( data.begin(), data.end(), std::mem_fun_ref( &object::increase_by_one) );
In a code review, you would have an extra component to check of course, but that's another matter.
|
|
|
|
|
True, good naming removes most problems.
Cheers,
Ash
|
|
|
|