staticLRESULTCALLBACKStartWindowProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam){CContainedWindowT<TBase>*pThis=(CContainedWindowT<TBase>*)_Module.ExtractCreateWndData();ATLASSERT(pThis!=NULL);pThis->m_hWnd=hWnd;pThis->m_thunk.Init(WindowProc,pThis);WNDPROCpProc=(WNDPROC)&(pThis->m_thunk.thunk);WNDPROCpOldProc=(WNDPROC)::SetWindowLong(hWnd,GWL_WNDPROC,(LONG)pProc);#ifdef_DEBUG//checkifsomebodyhassubclassedusalreadysincewediscardit
if(pOldProc!=StartWindowProc)ATLTRACE2(atlTraceWindowing,0,_T("Subclassingthroughahookdiscarded.\n"));#elsepOldProc;//avoidunusedwarning
#endifreturnpProc(hWnd,uMsg,wParam,lParam);}
class CWndProcThunk
{
public:
union
{
_AtlCreateWndData cd;
_WndProcThunk thunk;
};
void Init(WNDPROC proc, void* pThis)
{
#if defined (_M_IX86)
thunk.m_mov = 0x042444C7; //C7 44 24 0C
thunk.m_this = (DWORD)pThis;
thunk.m_jmp = 0xe9;
thunk.m_relproc = (int)proc - ((int)this+sizeof(_WndProcThunk));
#elif defined (_M_ALPHA)
thunk.ldah_at = (0x279f0000 | HIWORD(proc)) + (LOWORD(proc)>>15);
thunk.ldah_a0 = (0x261f0000 | HIWORD(pThis)) + (LOWORD(pThis)>>15);
thunk.lda_at = 0x239c0000 | LOWORD(proc);
thunk.lda_a0 = 0x22100000 | LOWORD(pThis);
thunk.jmp = 0x6bfc0000;
#endif
// write block from data cache and
// flush from instruction cache
FlushInstructionCache(GetCurrentProcess(), &thunk, sizeof(thunk));
}
};
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CContainedWindowT< TBase >* pThis = (CContainedWindowT< TBase >*)hWnd;
ATLASSERT(pThis->m_hWnd != NULL);
ATLASSERT(pThis->m_pObject != NULL);
// set a ptr to this message and save the old value
MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } };
const MSG* pOldMsg = pThis->m_pCurrentMsg;
pThis->m_pCurrentMsg = &msg;
// pass to the message map to process
LRESULT lRes;
BOOL bRet = pThis->m_pObject->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, pThis->m_dwMsgMapID);
// restore saved value for the current message
ATLASSERT(pThis->m_pCurrentMsg == &msg);
pThis->m_pCurrentMsg = pOldMsg;
// do the default processing if message was not handled
if(!bRet)
{
if(uMsg != WM_NCDESTROY)
lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
else
{
// unsubclass, if needed
LONG pfnWndProc = ::GetWindowLong(pThis->m_hWnd, GWL_WNDPROC);
lRes = pThis->DefWindowProc(uMsg, wParam, lParam);
if(pThis->m_pfnSuperWindowProc != ::DefWindowProc && ::GetWindowLong(pThis->m_hWnd, GWL_WNDPROC) == pfnWndProc)
::SetWindowLong(pThis->m_hWnd, GWL_WNDPROC, (LONG)pThis->m_pfnSuperWindowProc);
// clear out window handle
pThis->m_hWnd = NULL;
}
}
return lRes;
}
相关推荐
ATL作为一个生成C++/COM代码的框架,与C语言生成汇编代码的角色类似。因此,推荐读者在学习ATL前,先阅读Don Box的《Essential COM》以掌握COM的基础知识。 《ATL Internals》不仅提供了ATL的深入技术解析,还包含...
在VS2010中,默认情况下,汇编代码可能没有颜色高亮显示,这可能会影响开发者的阅读和理解。为了改善这种情况,WTL 8.1修善版附带了一个名为usertype.dat的文件,当导入到Visual Studio中时,可以增强对汇编语言的...
在代码中调用ShellExecute并设置断点,然后在Debug -> Windows -> Disassembly中查看汇编代码。这将揭示函数内部的执行流程,让我们有机会单步执行并理解其工作原理。 总的来说,追踪Windows API涉及到设置Symbol...
15. **生成汇编代码**:在项目设置中选择特定文件,将List Files Type设为Assembly and source code,指定输出汇编代码的文件,编译后即可得到相应源文件的汇编代码。 16. **手工编译纯资源成DLL**:通过Rc.exe、...
这包括了对内联汇编语言代码的调试,以及在Windows平台下使用特定的调试工具来定位、分析和修复Windows代码中的错误。 当开发使用MFC类库的Windows程序时,调试技巧同样适用,但需要结合MFC框架的特点来定位和分析...
15. **生成汇编代码**:在“Project->Setting”中设置,选择指定文件,然后在“List Files Type”中选择“Assembly and source code”,最后指定输出汇编代码的文件名,编译后即可得到源代码的汇编版本。 16. **...
中间代码的生成使得编译器能够处理不同的目标平台,因为它们不需要直接生成特定机器的汇编代码。 在“co_test”文件中,可能是编译器的测试用例或者测试代码,用于验证编译器各阶段的功能正确性。通过运行这些测试...
1. **汇编语言**:学习汇编,可以通过分析CIH病毒的源代码,虽然只有1000行,但足以了解其运作机制。 2. **C语言**:要掌握C,研究Linux内核的IP栈源代码是很好的实践,这涉及几万行核心代码。 3. **C++**:对于MFC...
14. **生成汇编代码**:在Project->Setting中选择指定文件,设置List Files Type为Assembly and source code,编译后会生成对应的汇编代码文件。 15. **手工编译纯资源成DLL**:通过Rc.exe、Cvtres.exe和Link命令,...
6. **预处理指令定位**:使用`Ctrl+K`可以在源文件中快速定位到匹配的`#if`和`#endif`,有助于理解代码结构。 7. **添加系统库到项目**:在`Project` -> `Settings` -> `Link` -> `Object/library modules`中输入...
在微机原理课程设计中,交通控制灯的模拟通常是一个典型的实践项目,它涉及到计算机硬件与软件的交互,以及对微处理器操作的理解。在这个设计中,电子秒表的实现是核心部分,它利用了汇编语言来编程,这是一种低级...
6.2.5 查看反汇编代码 6.3 进一步观察变量 6.3.l 使用QuickWatch窗口 6.3.2 使用Watch窗口 6.4 小结 第7章 调试内联汇编语言代码 7.l 汇编语言初步 7.1.l 数据类型 7.1.2 寄存器 7.1.3 寻址模式 ...
5. **编译与链接**:理解编译器如何将源代码转换为可执行文件,包括预处理、编译、汇编和链接的步骤。 6. **调试技巧**:学会使用IDE的调试器进行单步调试,查看变量值,设置条件断点等。 7. **MFC与Windows API**...
在VC++6.0中,源代码经过预处理、编译、汇编和链接四个步骤,生成可执行文件。理解这些过程有助于优化代码性能和解决编译错误。 7. **项目管理和配置** 用户可以通过项目管理器组织源代码文件,并进行编译设置,...
- **处理器编译器**:针对平台特定的交叉编译器和交叉汇编器,允许开发者在不同架构间编译代码。 - **开发工具**:ErrorLookup、GuidGen、Link和Nmake等,涵盖了错误查询、GUID生成、链接及构建管理等功能。 - **...
此外,它的调试器也是一个强大的工具,可以用来查找和修复程序中的错误,这对于学习和理解程序执行流程至关重要。 精简版可能去掉了某些高级特性,如MFC(Microsoft Foundation Classes)库,这是一个用于构建...
执行(Execute)运行程序,调试(Debug)则通过设置断点、单步执行、监视变量、查看汇编代码和调用堆栈等功能,帮助找出并修复错误。调试工具包括Start Debug、Go、Step Into、Step Over、Step Out和Break Point等...