在一个MFC扩展DLL中创建一个child类型的NONE Boder的对话框,并在改对话框中假如工具栏。在外部调用时失效

有人在CHILD类型的对话框内加入工具栏吗?最近弄一个MFC扩展DLL,把对话框类放在DLL中。便于模块化编程当在外部把这个对话框嵌入VIEW中作为子窗口时是发现DEBU... 有人在CHILD类型的对话框内加入工具栏吗
?
最近弄一个MFC扩展DLL,把对话框类放在DLL中。
便于模块化编程
当在外部把这个对话框嵌入VIEW中作为子窗口时是发现DEBUG版本的对话框上的工具栏正常显示,而RELEASE的显示灰色
如果是POP类型和其它的正常就CHILD不正常,不知道有那位高手可以解答

如果100分不够,我可以给200分和300分,我用1000分,不惜代价,MONEY 也可以。
这是对话框头文件:
#pragma once

// CRoomStatusDialog 对话框

class CRoomStatusDialog : public CDialog
{
DECLARE_DYNAMIC(CRoomStatusDialog)

public:
CRoomStatusDialog(CWnd* pParent = NULL); // 标准构造函数
virtual ~CRoomStatusDialog();
void SetToolbarBitmap() ;
CToolBar m_wndToolBar;

// 对话框数据
enum { IDD = IDD_ROOMSTATUS };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// // afx_msg void OnStanderroom();
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSize(UINT nType, int cx, int cy);
// afx_msg void OnBtnBalcony();
// afx_msg void OnFloor();
// afx_msg void OnUpdateBtnBalcony(CCmdUI *pCmdUI);

// afx_msg void OnBtnBalcony();
};
源文件关键部分是:
BOOL CRoomStatusDialog::OnInitDialog()
{
CDialog::OnInitDialog();
/* SetToolbarBitmap();*/
// TODO: 在此添加额外的初始化

if (!m_wndToolBar.CreateEx( this,TBSTYLE_FLAT , WS_CHILD | TBSTYLE_LIST|
WS_VISIBLE | CBRS_ALIGN_TOP | CBRS_GRIPPER
| CBRS_TOOLTIPS)|| !m_wndToolBar.LoadToolBar(IDT_RoomStatus) )
{
TRACE0("failed to create toolbar\n");
return FALSE;
}
m_wndToolBar.ShowWindow(SW_SHOW);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
m_wndToolBar.GetToolBarCtrl().SetState(ID_BTN_Balcony, TBSTATE_ENABLED);
// SetToolbarBitmap();
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void CRoomStatusDialog::SetToolbarBitmap()
{
CImageList m_imageTool;
//// Load resource to prepare for Initialing
//
CString strName;
CBitmap bmpToolBar;
HBITMAP hbmpToolBar;
strName = "skin\\m_toolbot.bmp";
hbmpToolBar =(HBITMAP) LoadImage(NULL, strName, IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE);
bmpToolBar.Attach(hbmpToolBar);
m_imageTool.Create(20, 20, ILC_COLOR24|ILC_MASK, 9, 9);

m_imageTool.Add(&bmpToolBar,RGB(192,192,192));
m_wndToolBar.SendMessage(TB_SETIMAGELIST, 0,
(LPARAM)m_imageTool.m_hImageList);
m_imageTool.Detach();

if(m_imageTool.GetSafeHandle ()){
m_imageTool.DeleteImageList ();
}
}

我试过加入消息映射函数也无效,今天搞了7个小时同样没办法解决。我不信微软的东西连这个基本的问题都没有解答,希望高手能解答,我附上几副图片你看看。
展开
 我来答
fantasy1136
2011-09-09 · TA获得超过143个赞
知道答主
回答量:135
采纳率:0%
帮助的人:57.7万
展开全部
哪些情况下 Release 版会出错

有了上面的介绍,我们再来逐个对照这些选项看看 Release 版错误是怎样产生的

1. Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的 Runtime Library 通常很稳定,不会造成 Release 版错误;倒是由于 Debug 的 Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现 Debug 有错但 Release 正常的现象。应当指出的是,如果 Debug 有错,即使 Release 正常,程序肯定是有 Bug 的,只不过可能是 Release 版的某次运行没有表现出来而已。

2. 优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:

(1) 帧指针(Frame Pointer)省略(简称 FPO ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误 ————但 Debug 方式下,栈的访问通过 EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略 EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在 Release 版本中强制加入 /Oy- 编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:

● MFC 消息响应函数书写错误。正确的应为
afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);
ON_MESSAGE 宏包含强制类型转换。防止这种错误的方法之一是重定义 ON_MESSAGE 宏,把下列代码加到 stdafx.h 中(在#include "afxwin.h"之后),函数原形错误时编译会报错
#undef ON_MESSAGE
#define ON_MESSAGE(message, memberFxn) \
{ message, 0, 0, 0, AfxSig_lwl, \
(AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \
CWnd::*)(WPARAM, LPARAM) > (&memberFxn) },

(2) volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于 register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确 的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上 volatile 试试。

(3) 变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在 Debug 版中它有可能掩盖一个数组越界,而在 Release 版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有:
● 非法访问,包括数组越界、指针错误等。例如
void fn(void)
{
int i;
i = 1;
int a[4];
{
int j;
j = 1;
}
a[-1] = 1;//当然错误不会这么明显,例如下标是变量
a[4] = 1;
}
j 虽然在数组越界时已出了作用域,但其空间并未收回,因而 i 和 j 就会掩盖越界。而 Release 版由于 i、j 并未其很大作用可能会被优化掉,从而使栈被破坏。

3. _DEBUG 与 NDEBUG :当定义了 _DEBUG 时,assert() 函数会被编译,而 NDEBUG 时不被编译。除此之外,VC++中还有一系列断言宏。这包括:

ANSI C 断言 void assert(int expression );
C Runtime Lib 断言 _ASSERT( booleanExpression );
_ASSERTE( booleanExpression );
MFC 断言 ASSERT( booleanExpression );
VERIFY( booleanExpression );
ASSERT_VALID( pObject );
ASSERT_KINDOF( classname, pobject );
ATL 断言 ATLASSERT( booleanExpression );
此外,TRACE() 宏的编译也受 _DEBUG 控制。

所有这些断言都只在 Debug版中才被编译,而在 Release 版中被忽略。唯一的例外是 VERIFY() 。事实上,这些宏都是调用了 assert() 函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用 等),那么 Release 版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用 VC++ 的 Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入 #ifdef _DEBUG 之类的条件编译,也要注意一下。
顺便值得一提的是 VERIFY() 宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查 Windows API 的返回值。有些人可能为这个原因而滥用 VERIFY() ,事实上这是危险的,因为 VERIFY() 违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。

4. /GZ 选项:这个选项会做以下这些事

(1) 初始化内存和变量。包括用 0xCC 初始化所有自动变量,0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如 new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如 delete ),0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且 32 位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在 Debug 版中发现 Release 版才会遇到的错误。要特别注意的是,很多人认为编译器会用 0 来初始化变量,这是错误的(而且这样很不利于查找错误)。
(2) 通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配)
(3) 函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略 FPO )

通常 /GZ 选项会造成 Debug 版出错而 Release 版正常的现象,因为 Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。

除此之外,/Gm /GF 等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。
--------------------------------------------------------------
Release是发行版本,比Debug版本有一些优化,文件比Debug文件小
Debug是调试版本,包括的程序信息更多
Release方法:
build->batch build->build就OK.

具体可以看看下面的链接
参考资料:http://hi.baidu.com/msingle/blog/item/57e8c8fb8fa294214f4aeaa8.html
更多追问追答
追问
我的没有出现错误就是在DEBUG下工具栏能显示正常,但是在RELEASE下,工具栏是灰色的,处于禁用状态。而.代码是相同的,就是选择生成EXE的方式不同。我怎么调都不知道什么原因。我代码也可以给你分析,不到2千行代码。
我这个就是在一个CHILD类型的对话框中用到工具栏,而工具栏是灰色的。我尝试加消息处理函数,也一样。在一个程序中加载带有这个的DLL,然后生成DEBUG版本是能正常显示,而RELEASE版本的工具栏处于禁用状态。
追答
邮箱1203655224@qq.com 如果方便的话可以给我看看,但我也没把握搞好,不过可以多一个人调试
百度网友0728493
2011-09-10
知道答主
回答量:19
采纳率:0%
帮助的人:19.8万
展开全部
使用MFC扩展dll时要注意,导出函数时要切换资源,加上这句话
AFX_MANAGE_STATE(AfxGetStaticModuleState());
更多追问追答
追问
没用,我的资源可以正常使用,DLL的也可以。我上面的截图你看,一个DEBUG的下面工具栏是亮的,而RELEASE版本的却是灰的。如果资源切换有问题应该什么都看不到才是。因为资源在DLL里,如果切换有问题则资源应该是EXE的,应该要不不显示要不弹出出错,我是间接调用的。
追答
不好意思没注意看,工具栏之类的程序没做过。不过debug和release不同...
没有源码很难判断出问题,你可以看看图片的路径啦,比如release版的release目录下有skin\..那个图么?还有条件编译之类的
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
ufo1cn
2011-09-09 · TA获得超过448个赞
知道小有建树答主
回答量:412
采纳率:0%
帮助的人:223万
展开全部
没试过这样干,不过会不会是dll模块句柄 和主程序模块句柄不一致导致有些函数调用错误。比如获取资源的函数。
更多追问追答
追问
之前确实遇到这样的,后来我用一个类作为导出类,而这个类内部函数才调用这个对话框,
主程序是调用这个类的函数,间接调用产生这个对话框的,而资源在DLL里,如果冲突他应该
不显示工具栏,或者弹出一个错误。而这个是显示工具栏,只不过上面显示的是禁用状态。
我尝试用SetSate以及EnableWindow,甚至映射了消息处理函数,然后在更新函数部分让Enable参数为true也不行。而无论不做什么在DEBUG下都正常,RELEASE却显示禁用。
追答
看看资源文件中dll和应用程序使用的ID号是否有重复的。在Release 和debug下分别用动态连接和静态连接mfc 库 并用spy类的工具看看窗口样式有什么区别,比如spy4win就不错,看看窗口属性,看看收到的windows消息。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
paniclp
2011-09-10 · TA获得超过232个赞
知道小有建树答主
回答量:700
采纳率:0%
帮助的人:433万
展开全部
有代码么,发我一份看看,
qq64924930
追问
给你发QQ好友请求了,当然如果不想加我也行,我们可以邮箱交流。这些积分都是小事,我回答一些简单的问题很快就有积分。呵呵。
现在问题解决了,谢谢你!但是我积分只能给之前为此付出很多的人,因为百度只支持给1个人积分。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
善良的屠夫tu
2011-09-09 · TA获得超过228个赞
知道小有建树答主
回答量:240
采纳率:0%
帮助的人:169万
展开全部
听不懂问题
追问
那你觉得我需要再补充哪些你才能了解我的问题?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 2条折叠回答
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式