最近項目中的Win32開發技巧拾遺

1.       WinSock的初始化和關閉的智能管理。

使用全局static對象,可實現在模塊被調用時初始化WinSock,在模塊卸載時關閉WinSock

#include <winsock2.h>

#pragma comment(lib, "Ws2_32.lib")

 

class CWinSockGuard

{

public:

    CWinSockGuard()

    {

       m_bInitOK = false;

       WORD wVersionRequested = MAKEWORD(1, 1);

       WSADATA wsaData;

       int nReturnCode = WSAStartup(wVersionRequested, &wsaData);

       switch(nReturnCode)

       {

       case 0:                  //OK  

           {

              m_bInitOK = true;

              break;

           }

       case WSASYSNOTREADY: //the underlying network subsystem is not ready for network communication

       case WSAVERNOTSUPPORTED://The version of Windows Sockets support requested is not provided.

       case WSAEFAULT:          //The lpWSAData parameter is not a valid pointer.

           {

              m_bInitOK = false;

              break;

           }

       }

    }

    ~CWinSockGuard()

    {

       if(m_bInitOK)

       {

           WSACleanup();

       }

    }

private:

    bool m_bInitOK;

};

//Just make sure we Init and Cleanup WinSock module properly

static CWinSockGuard g_cWinSockGuard; 

 

2.       WinSockUDPrecvfrom函數返回值處理。

           if(nRecvLength == SOCKET_ERROR)

           {

              //返回-1一般是出錯的情況,可調用WSAGetLastError獲得錯誤碼,一般情形下可忽略該問題,繼續接收數據。

              //If an error occurs,a value of SOCKET_ERROR is returned,

              //and a specific error code can be retrieved by calling WSAGetLastError.

              int nErrorCode = WSAGetLastError();

             

              //UDP中返回10054的問題:一般是在當調用sendto發送到一個UDP端口未開啓的對端時,selecet顯示有數據可斷,調用recvfrom返回-1,錯誤碼爲:10054,該問題可忽略,繼續接收數據即可。

              //If a SendData request is sent to a RemoteHost that is not listening on the RemotePort,

              //the DataArrival event fires and indicates that 1 byte of data is available.

              //When you call the GetData method to retrieve that data, the following run-time error occurs:

              //'10054' - "The connection is reset by remote side".

              continue;

           }

           else if(nRecvLength == 0)

           {

              //返回0,一般是本地套接字已關閉(本線程或其它線程可能調用了closesocket),此時不應再接收數據

              //If the connection has been gracefully closed, the return value is zero.

              break;

           }

 

3.       64位整型數據的處理問題。

數據的打印,在WIN32中,一般使用:%I64d%I64u,分別對應__int64unsigned __int64。而在GCC中,一般使用:%lld%llu,分別對應unsigned long longlong long

數據的隨機生成方法:

(UINT64)((UINT64)rand() ^  ((UINT64)rand() << 15) ^  ((UINT64)rand() << 30) ^ ((UINT64)rand() << 45) ^  ((UINT64)rand() << 60))

 

4.       使用Dependency Walker查看VS2005編譯出來的dll中,發現依賴msvcp80.dllmsvcr80.dll出現問號的問題!

建立一個dll工程,默認“使用標準 Windows 庫”,編譯出來的dll文件用dependency打開,發現包含一個MSCVR80.dll,並且前面打着問號。使用這個dll的程序在未安裝vc的電腦上不能運行。解決方法:在工程設置裏選擇“在靜態庫中使用 MFC”,保存。然後再選擇回“使用標準 Windows 庫”,保存。重新編譯dll。用dependency查看可以發現MSCVR80.dll已經沒有了。

http://blog.csdn.net/sunrisemaple/archive/2008/04/27/2334573.aspx

 

5.       Windows消息隊列函數重溫

備註:Windows消息隊列函數以下函數的特點耐人尋味(GetMessage, PeekMessage, PostMessage, PostThreadMessage, SendMesage)

其中PeekMessage的調用是立即返回的,並不等待消息隊列中有消息才返回,並且對於WM_QUIT消息的處理與GetMessage也是不同的,值得關注。

 

GetMessage

This function retrieves a message from the calling thread's message queue and places it in the specified structure.

Return Values

Nonzero indicates that the function retrieves a message other than WM_QUIT. Zero indicates that the function retrieves the WM_QUIT message, or that lpMsg is an invalid pointer. To get extended error information, call GetLastError.

 

PeekMessage

This function checks a thread message queue for a message and places the message (if any) in the specified structure.

wRemoveMsg

[in] Specifies how messages are handled. This parameter can be one of the following values.

Value

Description

PM_NOREMOVE

Messages are not removed from the queue after processing by PeekMessage.

PM_REMOVE

Messages are removed from the queue after processing by PeekMessage. An exception is WM_PAINT messages, which are not removed from the queue.

You can optionally combine the value PM_NOYIELD with either PM_NOREMOVE or PM_REMOVE. This flag prevents the system from releasing any thread that is waiting for the caller to go idle.

Return Values

Nonzero indicates success. Zero indicates failure.

Unlike the GetMessage function, the PeekMessage function does not wait for a message to be placed in the queue before returning.

 

PostMessage

This function places a message in the message queue associated with the thread that created the specified window and then returns without waiting for the thread to process the message.

PostThreadMessage

This function places a message in the message queue of the specified thread and then returns without waiting for the thread to process the message.

SendMessage

This function sends the specified message to a window or windows.

 

發佈了86 篇原創文章 · 獲贊 2 · 訪問量 56萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章