如何在C中调用 Dlg类中函数?

ppcust 2010-11-29 04:32:42
创建一个abc dlg 。
在abcdlg.cpp中

void testoutc()
{
如何调用 testout();
}


void CAbcDlg::testout()
{
MessageBox("hello world");
}

问题是: 如何在 testoutc()中调用 类中的 testout?

好像有几种方法。什么通过类的指针什么的,望高手指点~
...全文
315 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sd6814466 2010-12-01
  • 打赏
  • 举报
回复
我也暗暗怀疑,c文件中能支持类么?依然按照C++来编译?
cranium 2010-12-01
  • 打赏
  • 举报
回复
贴个我保存的一份代码,作者不详。

MembFun.cpp

#include "stdafx.h"

typedef unsigned int DWORD;

//取类成员函数的地址.vc8版本.可以取私有成员函数地址.
#define GetMemberFuncAddr_VC8(FuncAddr,FuncType)\
{ \
__asm \
{ \
mov eax,offset FuncType \
}; \
__asm \
{ \
mov FuncAddr, eax \
}; \
}

//取类成员函数的地址.vc6版本.
template <class ToType, class FromType>
void GetMemberFuncAddr_VC6(ToType& addr,FromType f)
{
union
{
FromType _f;
ToType _t;
}ut;

ut._f = f;

addr = ut._t;
}

//调用类成员函数
DWORD CallMemberFunc(int callflag,DWORD funcaddr,void *This,int count,...)
{
DWORD re;

if(count>0)//有参数,将参数压入栈.
{
__asm
{
mov ecx,count;//参数个数,ecx,循环计数器.

mov edx,ecx;
shl edx,2;
add edx,0x14; edx = count*4+0x14;

next: push dword ptr[ebp+edx];
sub edx,0x4;
dec ecx
jnz next;
}
}

//处理this指针.
if(callflag==0) //__thiscall,vc默认的成员函数调用类型.
{
__asm mov ecx,This;
}
else//__stdcall
{
__asm push This;
}

__asm//调用函数
{
call funcaddr; //call 1.向堆栈中压入下一行程序的地址;2.JMP到call的子程序地址处。
mov re,eax;
}

return re;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
void test1()//演示c++成员函数指针的用法.
{
class tt
{
public: void foo(int x){ printf("\n %d \n",x); }
};

typedef void (tt::* FUNCTYPE)(int);


FUNCTYPE ptr = &tt::foo; //给一个成员函数指针赋值.

tt a;
(a.*ptr)(5); //调用成员函数指针.

tt *b = new tt;
(b->*ptr)(6); //调用成员函数指针.

delete b;
// DWORD dwFooAddrPtr= 0;
// dwFooAddrPtr = (DWORD) &tt::foo; /* Error C2440 */
// dwFooAddrPtr = reinterpret_cast<DWORD> (&tt::foo); /* Error C2440 */
}

void test2()//示范如何取成员函数地址.
{
class tt
{
public: void foo(int x){ printf("\n %d \n",x); }
};

#if _MSC_VER >1200
DWORD dwAddrPtr1;
GetMemberFuncAddr_VC8(dwAddrPtr1,tt::foo);
printf("\n test2 tt::foo %08x",dwAddrPtr1);
#endif

DWORD dwAddrPtr2;
GetMemberFuncAddr_VC6(dwAddrPtr2,&tt::foo);
printf("\n test2 tt::foo %08x",dwAddrPtr2);
}

void test3()//示范如何调用成员函数地址.
{
class tt
{
public:

void foo(int x,char c,char *s)//没有指定类型,默认是__thiscall.
{
printf("\n m_a=%d, %d,%c,%s\n",m_a,x,c,s);
}

void __stdcall foo2(int x,char c,char *s)//成员函数指定了__stdcall调用约定.
{
printf("\n m_a=%d, %d,%c,%s\n",m_a,x,c,s);
}

int m_a;
};

typedef void (__stdcall *FUNCTYPE) ( int,char,char*);//定义对应的非成员函数指针类型,注意指定__stdcall.
typedef void (__stdcall *FUNCTYPE2)(void *,int,char,char*);//注意多了一个void *参数.

tt abc;
abc.m_a = 123;

DWORD ptr;
DWORD This = (DWORD)&abc;

GetMemberFuncAddr_VC6(ptr,&tt::foo); //取成员函数地址.

FUNCTYPE fnFooPtr = (FUNCTYPE) ptr;//将函数地址转化为普通函数的指针.

__asm //准备this指针.
{
mov ecx, This;
}

fnFooPtr(5,'a',"7xyz"); //象普通函数一样调用成员函数的地址.


GetMemberFuncAddr_VC6(ptr,&tt::foo2); //取成员函数地址.

FUNCTYPE2 fnFooPtr2 = (FUNCTYPE2) ptr;//将函数地址转化为普通函数的指针.

fnFooPtr2(&abc,5,'a',"7xyz"); //象普通函数一样调用成员函数的地址,注意第一个参数是this指针.
}

void test4()//示范通过CallMemberFunc调用成员函数
{
class tt
{
public:

void foo(int x,char c,char *s)//没有指定类型,默认是__thiscall.
{
printf("\n m_a=%d, %d,%c,%s\n",m_a,x,c,s);
}

void __stdcall foo2(int x,char c,char *s)//成员函数指定了__stdcall调用约定.
{
printf("\n m_a=%d, %d,%c,%s\n",m_a,x,c,s);
}

int m_a;
};

tt abc;
abc.m_a = 123;

DWORD ptr1,ptr2;

GetMemberFuncAddr_VC6(ptr1,&tt::foo); //取成员函数地址.
GetMemberFuncAddr_VC6(ptr2,&tt::foo2); //取成员函数地址.

CallMemberFunc(0,ptr1,&abc,3,5,'a',"7xyz");//第一个参数0,表示采用__thiscall调用.
CallMemberFunc(1,ptr2,&abc,3,5,'a',"7xyz");//第一个参数1,表示采用非__thiscall调用.
}

void test5()//示范在继承情况下使用函数地址.
{
class tt1
{
public:
void foo1(){ printf("\n hi, i am in tt1::foo1\n"); }
virtual void foo3(){ printf("\n hi, i am in tt1::foo3\n"); }
};

class tt2 : public tt1
{
public:
void foo2(){ printf("\n hi, i am in tt2::foo2\n"); }
virtual void foo3(){ printf("\n hi, i am in tt2::foo3\n"); }
};


DWORD tt1_foo3,tt2_foo1,tt2_foo2,tt2_foo3;

GetMemberFuncAddr_VC6(tt1_foo3,&tt1::foo3);
GetMemberFuncAddr_VC6(tt2_foo1,&tt2::foo1);
GetMemberFuncAddr_VC6(tt2_foo2,&tt2::foo2);
GetMemberFuncAddr_VC6(tt2_foo3,&tt2::foo3);

tt1 x;
tt2 y;

CallMemberFunc(0,tt1_foo3,&x,0); // tt1::foo3
CallMemberFunc(0,tt2_foo1,&x,0); // tt2::foo1 = tt1::foo1
CallMemberFunc(0,tt2_foo2,&x,0); // tt2::foo2
CallMemberFunc(0,tt2_foo3,&x,0); // tt2::foo3

CallMemberFunc(0,tt1_foo3,&y,0); // tt1::foo3
CallMemberFunc(0,tt2_foo1,&y,0); // tt2::foo1 = tt1::foo1
CallMemberFunc(0,tt2_foo2,&y,0); // tt2::foo2
CallMemberFunc(0,tt2_foo3,&y,0); // tt2::foo3
}

int main(int argc, char* argv[])
{
test1();
test2();
test3();
test4();
test5();

return 0;
}
kusey 2010-12-01
  • 打赏
  • 举报
回复
testout 是类的成员函数,c 语言根本不认识类,不能调用 !
  • 打赏
  • 举报
回复
testout是CAbcDlg类的成员函数,你要先创建CAbcDlg的实例,通过实例直接调用就行,ls说的用静态函数不行,MessageBox是非静态的
witchman___ 2010-11-30
  • 打赏
  • 举报
回复
方法有很多种
1.静态函数 在AbcDlg.h中声明 static void testout();
通过CAbcDlg::testout();直接调用

2.传类指针 将CAbcDlg 对象地址传出来赋给全局变量,通过全局变量调用函数
如:CAbcDlg m_dlg;
在stdfax.h声明extern CAbcDlg* g_pdlg;
赋值:g_pdlg = &m_dlg;
调用:g_pdlg->testout();

3.传函数指针 要求函数testout()是public的
其他过程同2

就想到这么多


cydcom205 2010-11-30
  • 打赏
  • 举报
回复
在你要调用的文件中加CAbcDlg* pDialog的指针,然后作为非模态对话框来调用,不要显示出来就可以

pDialog = new CSoundInDlg(this);
if(pDialog != NULL)
{
pDialog->Create(IDD_DIALOG_SOUNDIN,this);
CRect clientRect,dlgRect;
GetClientRect(&clientRect); //获取客户区窗口大小
ClientToScreen(clientRect); //转换为屏幕坐标
pDialog->GetWindowRect(&dlgRect); //获取对话框窗口大小
//移动对话框窗口
pDialog->MoveWindow(160, 450,dlgRect.Width(),dlgRect.Height());
pDialog->ShowWindow(SW_SHOW);
pDialog->OnBnClickedButtonRecord();
}
l6j1j8 2010-11-30
  • 打赏
  • 举报
回复
如果要在testoutc()函数中调用CAbcDlg::testout(),必须先知道CAbcDlg的实例是在什么地方创建的,否则楼上诸位的解决方法对楼主不一定有可操作性,如有问题楼主可以将代码发至512259596@qq.com,让我来帮你分析
ppcust 2010-11-29
  • 打赏
  • 举报
回复
我要在.c 里面调用的。

Hi
VisualEleven:
通过CAbcDlg类的指针,或者给CAbcDlg表示的HWND发送消息,在消息响应函数中调用testout()函数
;;
能不能给个例子? 我在网上找来些都有些错误


yuanweihuayan 2010-11-29
  • 打赏
  • 举报
回复
题目好像没说清楚。是指在类外调用这个函数吗?那直接声明一个对象在调用其函数即可
Eleven 2010-11-29
  • 打赏
  • 举报
回复
通过CAbcDlg类的指针,或者给CAbcDlg表示的HWND发送消息,在消息响应函数中调用testout()函数
大拙男 2010-11-29
  • 打赏
  • 举报
回复
domal不对么?

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧