在MainDlg函数中
\n\nLRESULT CMainDlg::OnDo(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)\n{\n\n CMyDlg* dlg = new CMyDlg;// it could be CMainDlg member var\n //dlg.pMain = this; // i want to SendMessage(pMain.m_hWnd...) in CMyDlg...but it don\'t \n // work...\n dlg->Create(m_hWnd);\n dlg->ShowWindow(SW_SHOW);\n return 0;\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n在CMyDlg中
\n\n class CMyDlg : public CDialogImpl<CMyDlg>, public CUpdateUI<CMyDlg>,\npublic CMessageFilter, public CIdleHandler, \npublic CWinDataExchange<CMyDlg>,\npublic CDialogResize<CMyDlg>\n\n\nLRESULT CMyDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)\n{\n DestroyWindow();\n\n }\n
Run Code Online (Sandbox Code Playgroud)\n\n所以 CMyDlg* dlg 指针将会丢失...(内存泄漏)
\n\n我在 google 上搜索模型对话框。请注意 msdn.com 中的该消息
\n\nhttp://msdn.microsoft.com/en-us/library/zhk0y9cw(VS.80).aspx …
我刚刚开始一个新的ATL/WTL项目,我想知道是否还需要全局_Module变量?
回到我开始使用WTL几年后,您需要(至少对于ATL 3.0)定义一个全局变量,例如:
CAppModule _Module;
Run Code Online (Sandbox Code Playgroud)
让ATL正常工作.但是最近我在某处读到了这可能不再需要了(但是向导生成的代码仍然使用它).我还搜索了Visual C++ include目录,它只在几个地方选择了_Module - 最着名的是ATL COM注册表内容.
那么我现在还需要定义一个全局变量来使用ATL吗?
我正在继承一个WTL组合框,我是所有者 - 绘制组合框的项目.控件具有属性CBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWVARIABLE
,我使用混合类COwnerDraw来实现DrawItem()和MeasureItem().当下拉列表关闭时,项目将正确绘制.但是,当下拉列表启动时,组合框控件为空,并且不绘制项目.我究竟做错了什么?
WTL类看起来像这样:
class CMyComboBox :
public CWindowImpl<CMyComboBox, CComboBox>,
public COwnerDraw<CMyComboBox>
{
public:
BEGIN_MSG_MAP_EX(CMyComboBox)
CHAIN_MSG_MAP(COwnerDraw<CMyComboBox>)
CHAIN_MSG_MAP_ALT(COwnerDraw<CMyComboBox>, 1)
END_MSG_MAP()
void DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDCHandle dc = lpDIS->hDC;
dc.FillSolidRect(&lpDIS->rcItem, lpDIS->itemID == 0 ?
RGB(255,0,0) : RGB(0,255,0));
}
void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
lpMeasureItemStruct->itemWidth = 12;
lpMeasureItemStruct->itemHeight = 12;
}
};
Run Code Online (Sandbox Code Playgroud)
该类用于对话框,并且是这样的子类:
m_cbMy.SubclassWindow(GetDlgItem(IDC_COMBO1));
m_cbMy.AddString(_T("Item 1"));
m_cbMy.AddString(_T("Item 2"));
Run Code Online (Sandbox Code Playgroud)
将控件属性更改为CBS_OWNERDRAWFIXED
不会更改任何内容.
编辑:感谢najmeddine的帮助,我发现我必须处理WM_PAINT以绘制实际的组合框,而不仅仅是下拉列表中的项目.不幸的是现在我还必须自己绘制组合框控件.有没有办法让GDI绘制边框并放箭头,这样我只需要绘制控件的"内部"?
我在过去几天才学到了一点ATL(在了解了纯粹的Win32之后是多少痛苦)并且还学习了WTL和MFC,从我看到的,有很多不同的字符串类可用于我.
我用来做这样的事情:
#include <tchar.h>
#include <string>
namespace std { typedef basic_string<TCHAR> _tstring; }
Run Code Online (Sandbox Code Playgroud)
然后_tstring
在我的代码中到处使用.在学习了一些ATL之后,我了解到有一个CString
课程atltmp.h
.显然,CString
WTL中还有另一个 CString
类,而MFC中还有另一个类.
我不知道我是否会坚持使用ATL,或者我是否会切换到WTL,MFC或其他东西.但是现在,我正在将我的Win32代码转换为ATL,我不知道要改变什么以及要保留什么.
我应该使用CString
而不是_tstring
?考虑到可执行文件大小(不包括共享库)和可移植性/兼容性,这样做有什么好处吗?
ATL支持使用
ALT_MSG_MAP
宏声明的备用消息映射.
每个备用消息映射都由您传递给的唯一编号标识ALT_MSG_MAP
.
使用备用消息映射,您可以在一个映射中处理多个窗口的消息.
请注意,默认情况下,CWindowImpl
不使用备用消息映射.
要添加此支持,请覆盖-derived类中的WindowProc
方法,CWindowImpl
并ProcessWindowMessage
使用消息映射标识符进行调用.
当我看到WTL时,我会看到如下消息映射:
BEGIN_MSG_MAP(CCommandBarCtrlImpl)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_FORWARDMSG, OnForwardMsg)
...
ALT_MSG_MAP(1) // Parent window messages
MESSAGE_HANDLER(WM_INITMENUPOPUP, OnParentInitMenuPopup)
...
ALT_MSG_MAP(2) // MDI client window messages
// Use CMDICommandBarCtrl for MDI support
ALT_MSG_MAP(3) // Message hook messages
MESSAGE_HANDLER(WM_MOUSEMOVE, OnHookMouseMove)
...
END_MSG_MAP()
Run Code Online (Sandbox Code Playgroud)
但是,我不明白:
他们如何被召唤.(代码如何知道备用消息映射的存在?)
它们与默认消息映射的区别.他们看起来都像是为同一个窗口处理相同类型的消息......
为什么它们有用.(它们不是都在同一个窗口吗?)
有没有人对替代消息映射有什么更好的解释?
(他们被发明的原因很有帮助.)
我有一个应用程序,我正在尝试调试崩溃.但是,由于以下几个原因很难检测到问题:
崩溃,我的意思是以下例外:
0xC0000005: Access violation reading location 0x00000000.
Run Code Online (Sandbox Code Playgroud)
您将使用什么策略来诊断此问题?
到目前为止我所做的是从我的程序中删除尽可能多的代码,直到我得到最小的导致崩溃的代码.它似乎发生在与项目静态链接的代码中,所以这也无济于事.
我有一个使用 WTL 8.1 开发的适用于 Windows XP SP3 的 VS2008 C++ 应用程序。我的应用程序包含一个选项卡控件,该控件在调整应用程序边框大小时会闪烁。
我的窗口层次结构如下所示:
CFrameWindowImpl CMainFrm
|-CSplitterWindow Splitter
|-CTabView Configuration Tabs
| |-CDialogImpl Configuration View 1
| |-CDialogImpl Configuration View 2
| |-CDialogImpl Configuration View 3
|-CDialogImpl Control View
Run Code Online (Sandbox Code Playgroud)
我尝试的解决方案是使CFrameWindowImpl
派生类使用该WS_EX_COMPOSITED
样式,并且其下面的所有窗口都使用该WS_EX_TRANSPARENT
样式。不幸的是,这使得选项卡控件按钮显示为空黑条,并且任何配置视图的控件根本不显示。
如果我删除WS_EX_COMPOSITED
和WS_EX_TRANSPARENT
样式,表单会正确显示,但CTabView
调整大小时,其下面的所有内容都会可怕地闪烁。
我需要更改什么才能消除闪烁并正确绘制控件?
谢谢,保罗
编辑:让它工作。我WS_EX_TRANSPARENT
按照马克·兰塞姆的建议删除了所有样式。我只将样式放在(包含在)WS_EX_COMPOSITED
上。其他控件根据需要通过 获得双缓冲。CTabCtrl
CTabView
WTL::CDoubleBufferImpl<>
我之前发布过这个问题,现在加载了本地化的字符串(我们用LoadString()得到的)但我还需要从附属DLL加载所有其他资源.
MFC有AfxSetResourceHandle()调用,但是我需要一些非mfc应用程序的东西吗?我怀疑我必须在初始化代码中设置它,所以我的所有资源都从另一个DLL加载.我如何在WTL(Windows模板库)上下文中执行此操作?
编辑:
我们不是直接使用win32,而是ATL和WTL用于Windows的东西.所以我们不能依赖MFC的东西,我们没有对菜单和对话框资源的加载进行低级控制.
编辑:嗯... 这似乎有一个答案,但我希望有更好的东西.例如 - 一个SetResourceInstance()方法,类似于CAppModule对象中的GetResourceInstance().
看来我没有什么小问题。
我将自己的窗口挂接到 IE 主窗口。我的窗口是从 WTL 的 CWindowImpl 派生出来的,并承载了 IWebBrowers2 控件,它显示了一些内容。
IWebBrowser2 显示带有<input type='text'/>
编辑框的html ,我需要支持所有键,这是编辑和操作文本所必需的(Ctrl + C、Ctrl + V、Ctrl + X 等... + Esc、删除、向上和向下箭头)。
另外我需要禁止一些快捷方式,例如 Ctrl + P、Ctrl + S,因为它们调用特定于我不需要的网页的对话框。
似乎是常见问题,我需要为 IWebBrowser2 对象调用 TranslateAccelerator。
网上有一些类似的问题——Tab键在IWebbrowser2中不起作用
解决方案——热键不起作用!!
这是一个非常有趣的线程,我只需要 -在托管的 Web 浏览器控件中处理 Control-C
所以,首先我需要为我的 IWebBrowser2 对象调用 TranslateAccelerator。但我必须先从键盘获取消息。
那么,让我们看看它的外观。
我的钩子窗口没有收到任何键盘输入消息。一个类为“Internet Explorer_Server”的窗口接收所有这些(实际上,它是 IWebBrowser2 中 IE 的一个 hwnd)。
所以我需要钩住这个 hwnd 的 window proc。
m_ieOldProc = (PROC)::SetWindowLongPtr ( hIEWnd, GWLP_WNDPROC, (LONG_PTR)_IEWndProc );
Run Code Online (Sandbox Code Playgroud)
在 hooked wnd proc 中,我执行以下操作:
// …
Run Code Online (Sandbox Code Playgroud) 我试图第一次创建一个子类控件,但我觉得我做错了.控件是一个Button,我放在设计器中.这是它的类:
class TTTField : public CButton
{
public:
BEGIN_MSG_MAP_EX(TTTField)
MSG_WM_INITDIALOG(OnInitDialog);
END_MSG_MAP()
TTTField operator=(const CWindow& btn);
private:
const BOOL OnInitDialog(const CWindow wndFocus, const LPARAM lInitParam);
};
Run Code Online (Sandbox Code Playgroud)
到目前为止没什么好看的.
但是,我无法真正实现在此控件中接收Windows消息.这很糟糕,考虑到尝试子类化控件的主要原因是这应该是一个可重用的类,具有可重用的自定义Paint行为.我想覆盖某些消息处理程序,同时保留那些我没有明确要求通常的CButton例程.
正如您所看到的,我实现了一个消息映射,但消息并没有进入.
这是我尝试设置此类的实例的方法:
TTTField fld;
Run Code Online (Sandbox Code Playgroud)
是我的主对话框类的成员变量.在本课程中,我添加了以下DDX_MAP:
BEGIN_DDX_MAP(TTTMainDialog)
DDX_CONTROL_HANDLE(IDC_BTN, fld)
END_DDX_MAP()
Run Code Online (Sandbox Code Playgroud)
IDC_BTN是设计器上按钮的id.
在TTTField的赋值运算符重载中,我有以下内容:
TTTField TTTField::operator=(const CWindow& btn)
{
Attach(btn);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
我觉得这个运算符重载可能是我的问题的根源,但我无法找到一个正确解释整个主题的网站,而不使用似乎过时了20年的代码.
我在这做错了什么?我现在真的迷路了.
wtl ×10
c++ ×7
atl ×5
winapi ×5
windows ×2
combobox ×1
flicker ×1
hook ×1
iwebbrowser2 ×1
message-map ×1
mfc ×1
ownerdrawn ×1
resources ×1
string ×1
visual-c++ ×1