UC故事 2011/11/24

1. Chat Module接收信息,并演示到UI上面的全过程:

STACK TRACE:

CChatMainDlg::ReceiveMessage(unsigned long 19923456, WTL::CString & {...}, WTL::CString & {...}, int 1, _charformatw * 0x00119fa8) line 589
CChatMainDlg::ReceiveData(const CInfoSID & {...}, unsigned long 54, unsigned char * const 0x01f65db8) line 545
CChatSession::OnReceiveData(const CInfoSID & {...}, const CInfoSID & {...}, DATA_Priority DATA_PRIORITY_HIGH, unsigned long 2, unsigned long 54, unsigned char * const 0x01f65db8) line 634
CConfSession::OnReceiveData(const CInfoSID & {...}, const CInfoSID & {...}, DATA_Priority DATA_PRIORITY_HIGH, unsigned long 2, unsigned long 54, unsigned char * const 0x01f65d31) line 514 + 49 bytes
CConference::HandleSessApplicationData(CInfoSvrSessApplicationData * 0x01f635d0) line 1972 + 96 bytes
CConference::OnReceiveData(CRtMessageBlock & {...}) line 1342
CConfConnection::OnReceiveData(CRtMessageBlock & {...}, IConnection * 0x01efdf5c) line 170
CRtIMConnection::OnReceive(CRtMessageBlock & {...}, IRtTransport * 0x01efbe90, CRtTransportParameter * 0x00000000) line 890 + 50 bytes
CRtEventOnReceive::OnEventFire() line 375 + 50 bytes
CRtEventQueueBase::ProcessOneEvent(IRtEvent * 0x01f121d0) line 229 + 12 bytes
CRtEventQueueBase::ProcessEvents(const std::list<IRtEvent *,std::allocator<IRtEvent *> > & {...}) line 217
CRtReactorBase::ProcessHandleEvent(void * 0xffffffff, long 256, int 0, int 1, int 0) line 324 + 18 bytes
CRtReactorWin32Message::Win32SocketWndProc(HWND__ * 0x00050804, unsigned int 1058, unsigned int 4294967295, long 256) line 115
USER32! 77d18734()
USER32! 77d18816()
USER32! 77d189cd()
USER32! 77d196c7()
WTL::CMessageLoop::Run() line 468 + 15 bytes
Run(char * 0x00141f37, int 1) line 207 + 11 bytes
LaunchConf(HINSTANCE__ * 0x00400000, char * 0x00141f37, int 1) line 318 + 13 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f37, int 1) line 85 + 20 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()

Q:Win32SocketWndProc()被调用是谁决定的?所有这些对象的实例化过程?

     A:在CRtReactorWin32Message::Open()中将Win32SocketWndProc注册了。 2011/12/04

Q:网络程序用的message loop与CMainFrame使用的消息循环是同一个吗?

       A:不同,因为在不同的线程中,一个是main (UI) thread,一个是network thread。 2011/12/04

 

2. 杂项

*   How to understand Win32SocketWndProc ?

Reactor模式相关文章:http://woshao.com/article/4ab7b9e8589911e099b5000c2959fd2a/

Windows Socket的WSAAsyncSelect模型


3. CRtReactorWin32Message

* 初始化

STACK TRACE

CRtReactorWin32Message::Open() line 163
CRtThreadReactor::Create(int 0, CRtThreadManager::TFlag TF_JOINABLE) line 40 + 19 bytes
CRtThreadManager::CreateReactorThread(int 0, IRtReactor * 0x01ef81d8, CRtThread * & 0x00000000) line 368 + 41 bytes
CRtThreadManager::InitMainThread(int 0, char * * 0x00000000) line 191 + 24 bytes
CRtThreadManager::Instance() line 132 + 15 bytes
RtCoInitialize() line 179 + 5 bytes
ILDebugStart(unsigned short 33201, void * 0x00000001) line 1482
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00141f37, int 1) line 83 + 8 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()

注:在WinMain()中启动Debug Service(为什么是Debug?名字很怪)时,CRtReactorWin32Message::Open()被呼叫,并在此函数中完成窗口WinSocket 32窗口响应函数的注册。


* CRtReactorWin32Message::Open

RtResult CRtReactorWin32Message::Open()
{
    RtResult rv = RT_ERROR_UNEXPECTED;
    g_pReactorWin3Instance = ::GetModuleHandle(NULL);
    RT_ASSERTE_RETURN(!m_hwndNotify, RT_ERROR_ALREADY_INITIALIZED);

#ifdef RT_ENABLE_CALENDAR_TIMER
    m_CalendarTimer.m_Est.Reset2CurrentThreadId();
#endif // RT_ENABLE_CALENDAR_TIMER

    rv = CRtReactorBase::Open();
    if (RT_FAILED(rv))
        goto fail;

    if (g_atomRegisterClass == 0) {
        WNDCLASS wc;
        wc.style = 0;
        wc.lpfnWndProc = Win32SocketWndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = sizeof(void*);
        wc.hInstance = g_pReactorWin3Instance;
        wc.hIcon = 0;
        wc.hCursor = 0;
        wc.hbrBackground = 0;
        wc.lpszMenuName = NULL;
        wc.lpszClassName = WIN32_SOCKET_CLASS_NAME;
        
        if ((g_atomRegisterClass = ::RegisterClass(&wc)) == 0) {
            RT_ERROR_TRACE_THIS("CRtReactorWin32Message::Open, RegisterClass() failed!"
                " err=" << ::GetLastError());
            rv = RT_ERROR_FAILURE;
            goto fail;
        }

        ......

      m_hwndNotify = ::CreateWindow(WIN32_SOCKET_CLASS_NAME, NULL, WS_OVERLAPPED, 0,
        0, 0, 0, NULL, NULL, g_pReactorWin3Instance, 0);
      if (!m_hwndNotify) {
        RT_ERROR_TRACE_THIS("CRtReactorWin32Message::Open, CreateWindow() failed!"
            " err=" << ::GetLastError());
        rv = RT_ERROR_FAILURE;
        goto fail;
    }
    ......

    ::SetWindowLong(m_hwndNotify, 0, (LONG)this)          

                ^  将当前对象(也就是CRtReactorWin32Message)指针存在Windows数据区中,

                ^ 供Windows Handler函数在处理的时候使用reactor->ProcessHandleEvent来处理。 2011/12/04

 

    ......

    return RT_OK;
    .......
}

Q: created an invisible window ?

     A:YES ! 

注:SetWindowLong(...)将当前Reactor对象存在m_hwndNotify窗口的index为0的特殊存储区域中,在后来的消息响应函数中可以据此找到此Reactor的实例。

 

例入网络上有信息传过来的时候,如下代码:

Win32SocketWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

 switch(uMsg)
 {
   case WM_WIN32_SOCKET_SELECT:

   ...

   CRtReactorWin32Message *pReactor= (CRtReactorWin32Message *)::GetWindowLong(hwnd, 0);

   pReactor->XXX();

   ......

}


Q: why cannot find Win32SocketWndProc function in the computers at home ?


4. WSAAsyncSelect

::WSAAsyncSelect(sListen, hWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE);



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值