|
If, in your function, you don't access members of the class then it makes more sense to make it static then implement it as ordinary member.
Veni, vidi, vici.
|
|
|
|
|
If I remember correctly, you can't declare a pointer to a non-static member function in native C++. If you need to keep the original functions as they are, I would add a static helper function which gets the class object pointer as additional parameter and calls the member function. Something like that:
int theClass::theFunctionCaller(theClass * obj, int theParam1)
{
if (obj != NULL)
obj->theFunction(theParam1);
}
bool globFunction (theClass * obj, funcPtr aFunction)
{
int anArg = 0;
int ret = aFunction(obj, anArg);
return true;
}
int theClass::anotherFunction(void)
{
globFunction (this, &theClass::theFunctionCaller, true);
}
If you need the globFunction() for different classes, you could pass the obj as void * and cast it back in the helper function, because you know which class it is for at that point.
|
|
|
|
|
Cheers.. I'm having a play with this but you've modified globFunction, which in my case I'm really trying to avoid. Also it wont build as it stands (you can't call non static functions from a static function).
error C2352: 'theClass::theFunction' : illegal call of non-static member function
|
|
|
|
|
If modifying your global function is out of the question, then you can only pass it either a global function or a static class function. There is no other way. As CPallini remarked, the type of a pointer to a nonstatic member function is incompatible with your function pointer type definition.
What's more: a pointer to a nonstatic member function requires more memory to store than a simple function pointer, so casting is out of the question, too!
The question is: what is your goal? You're converting code, so why can't you change that global function?
If you really can't, the only solution I can think of would be a wrapper function that calls your member function indirectly:
namespace wrapper {
class theClass* instance; int theClassWrapper(int arg) {
int ret = 0;
if (instance != nullptr)
ret = instance->theFunction(arg);
return ret;
}
};
int theClass::anotherFunction() {
wrapper::instance = this;
return globFunction(&wrapper::theClassWrapper, true);
}
I've put the required additional global variable and global function inside a namespace to minimize global namespace polution and risk of conflicts, but you cannot avoid these additional globals if you cannot modify your existing global function.
|
|
|
|
|
Thanks for the reply - my original question was based on the premise that my casting or function declaration was wrong in some way - actually it looks like getting a pointer to a non-static class function and then casting it to match the original 'C' functions isn't straightforward.
So solution 1 - make the function and all the class variables static.
solution 2 - examine the original 'C' function that takes the function pointer and re-implement it.
Thanks for looking.
|
|
|
|
|
It 'isn't straightforward' in the same sense that casting a double to char would be. The types are not the compatible, not even the same size.
|
|
|
|
|
Freak30 wrote: If I remember correctly, you can't declare a pointer to a non-static member function in native C++
Actually you can, e.g.
#include<iostream>
using namespace std;
class A
{
int i;
public:
A(int i):i(i){}
void show() { cout << i << endl;}
};
void (A::*pmfn)();
int main()
{
A a(7);
pmfn = &A::show;
(a.*pmfn)();
}
However (and of course) this kind of pointer is not compatible with C -like function pointers.
Veni, vidi, vici.
|
|
|
|
|
Ok, this is quite interesting. Of course the function pointer is now class specific, and you still need to pass a pointer to the class object. So it seems there is no way around changing the global function.
|
|
|
|
|
What you're trying to do makes no sense. You're trying to call a non-static member function without an instance of the class or any mechanism to identify one.
Steve
|
|
|
|
|
Hello Friends
I am trying to connect to USB Printer. For that I used SetupDi calls but not able to get devicePath using Enuminterface.
So, I tried to pass devicePath manually to CreateFile'first parameter o create Handle.
After searching a lot, I found that the H/W id is being used for devicepath and it is here that i found from registery
LPCWSTR devicePath = L "\\\\?\\USB\\VID_04A9&PID_10A2&REV_0109#{4d36e979-e325-11ce-bfc1-08002be10318}"
In curly brackets represent ClassID for Printer device.[tried USB ClassId too]
But I am getting INVALID_HANDLE always.
So,please let me know the what is right devicepath that i can pass to create file to get its handle.
Thanks In Advance.
Regards
Yogesh
|
|
|
|
|
Take a look at this snippet, it may give you an idea.
This is "under construction" code , not plug and pray!
I use it with strDevice = "USB".
There is a SetupDi API for getting "friendly name", somewhere in my messy code.
DWORD dwFlag = DIGCF_ALLCLASSES | DIGCF_PRESENT;
TRACE("\nSetupDiGetClassDevs %s ", strDevice);
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL,strDevice, NULL,dwFlag);
if( INVALID_HANDLE_VALUE == hDevInfo ) {
TRACE("\nINVALID_HANDLE_VALUE == hDevInfo ");
return false;
}
TRACE("\nFind all selected devices %s",strDevice);
SP_DEVINFO_DATA* pspDevInfoData =
(SP_DEVINFO_DATA*)HeapAlloc(GetProcessHeap(), 0, sizeof(SP_DEVINFO_DATA));
pspDevInfoData->cbSize = sizeof(SP_DEVINFO_DATA);
int i = 0;
DWORD DataT ;
DWORD nSize=0 ;
TCHAR buf[MAX_PATH];
while (SetupDiEnumDeviceInfo(hDevInfo,i,pspDevInfoData))
{
SetupDiGetDeviceInstanceId(hDevInfo, pspDevInfoData, buf, sizeof(buf), &nSize);
{
TRACE("\nFind LittelWire ");
CString strTest = buf;
// CString strResult = strTest.SpanIncluding("0C9F");
int iFoundIndex = strTest.Find(strDeviceID);
TRACE("\nCount %i Buffer %s",i, buf);
if(iFoundIndex > 0 )
{
TRACE("\nCount %i Buffer %s Device %s found", i, buf, strDeviceID);
return true;
}
}
i++;
}
TRACE("\nDevice %s not found", strDeviceID);
return false;
|
|
|
|
|
Hi,
i have a dialog box and a picture control on that dialog box in mfc. I want to create a button on the right of the screen (similar to "Feedback" button seen on various sites). I created a button and positioned it on the right of the screen, but when clicked on any other control of the dialog box, the button hides under the picture control canvas.
Anybody have any idea.?
Any help will be appreciated.
Regards,
Mbatra
|
|
|
|
|
It sounds like the picture is being redrawn so it will obviously cover the button. Try positioning the button somewhere else.
|
|
|
|
|
Hi,
Thanx for the reply.
I have to show the buttons at the right of the screen. Similar to "Feedback" button we normally see on various sites.
I have one doubt, My computer screen size is larger compared to some others. So I want to ask should I use the GetWindowRect() OR GetClientRect() function to compute the size of the screen, because if I do it according to my screen size and position the buttons at the right of the screen, For a computer with smaller screen size, it will not be properly visible.
Regards,
Mbatra
|
|
|
|
|
mbatra31 wrote: For a computer with smaller screen size, it will not be properly visible. That's rather obvious. You should always check the Window, Client or Screen size depending on where you want your controls positioned.
|
|
|
|
|
Hi,
Its done..! Issue was with the positioning only.
Thanx for the help.
Regards,
Mbatra
|
|
|
|
|
From what Richard replied, and re-reading your message, I guess you have a button, and a picture control on your dialog, and they overlap.
What you need is a button which shows its own picture. You can attach an icon to the button from the resource editor, or you can use one of the many picture button controls available here:
http://www.codeproject.com/KB/buttons/[^]
Iain.
I am one of "those foreigners coming over here and stealing our jobs". Yay me!
|
|
|
|
|
Hi Iain,
I have a button and a bitmap. I am using CSkinButton class to set normal & hover state bitmaps on the button. I want to position the button on the right of the screen (similar to "feedback" button we normally see on various websites.) Now my computer screen size is larger, So when I position the buttons on the right side according to my computer screen size, its ok , but if I use this exe on some other computer which has a smaller screen size, button are not visible properly.
I want to place the buttons in the middle-right of the screen.
Regards,
Mbatra
|
|
|
|
|
Just position it somewhere where the controls don't overlap. You can have overlapping controls but it's really not worth the hassle. By the way, you can always get the size and position of your other control and do some math to figure out the proper placement of the button under it (if you're creating the controls at run-time).
|
|
|
|
|
I find that if the UI thread is block. it will be blocked when call CListCtrl::GetItemCount().
I want to know how the MFC low level to achieve this function?
If I use the MsgWaitForMultiObjects to block UI thread. How to set the QS_ALLINPUTS?
|
|
|
|
|
I'm not sure if I understand you correctly.
But you can see how wait functions work here - Halt! Who Goes There?[^]
|
|
|
|
|
Low level of MFC is the Win32 API. Open the context menu by right clicking on a call to CListCtrl::GetItemCount() and choose 'Go to definition'. You will see that it is an inline function that sends the LVM_GETITEMCOUNT message to the list control window. This message is not processed while your GUI thread is blocked.
A general rule is: Never block GUI threads. If you have to wait for events, do this in worker threads.
|
|
|
|
|
Hi Jochen Arndt,
You are very nice. But why I cannot see the source code of CListCtrl::GetItemCount()?
My develop tools is visual studio 2008.
|
|
|
|
|
I don't know why. You may also place the cursor on the call and press F12. With VS 2003 here, the MFC CListCtrl::GetItemCount() code is located in the VC subdirectory atlmfc\include\afxcmn.inl.
I suggested to look on the MFC sources so that you can see that most functions will only (or besides other tasks) just send messages.
If you don't have used the 'Go to definition' feature so far, give it a try. It is very useful. Not only for MFC functions, but also for your own ones to quickly see the source.
|
|
|
|
|
Thank you Jochen Arndt
I search the visual studio installed folder, and then find this file. It's greatly thing to see the MFC controls source.
|
|
|
|