标签: win32

  • WIN32 主线程中不能使用 WaitForSingleObject

    主线程中不能使用 WaitForSingleObject(m_GameProcessInfo.hProcess, INFINITE);

    这样会造成莫名奇妙的问题,比如我在一个项目这样用了,结果客户反馈说程序会造成鼠标一在转圈圈。经远程远程客户机排查,结果就是在主线程中使用WaitForSingleObject(m_GameProcessInfo.hProcess, INFINITE); 导致了主线程消息循环阻塞而引发的。

    经过在网上查找,很快找到了解决方案,用下面的代码取代WaitForSingleObject.

    while (TRUE)
    {
        DWORD result;
        MSG msg;
    
        result = MsgWaitForMultipleObjects(1, &m_GameProcessInfo.hProcess,
                   FALSE, INFINITE, QS_ALLINPUT);
    
        if (result == ( WAIT_OBJECT_0))
        {
            break;
        }
        else
        {
            PeekMessage(&msg, NULL , 0, 0, PM_REMOVE );
            DispatchMessage(&msg);
        }
    }

    微软对此函数的解释是:

    为了解决在主线程中Wait的问题,微软专门设计了一个函数MsgWaitForMultipleObjects,这个函数即可以等待信号(thread,event,mutex等等),也可以等待消息(MSG)。即不论有信号被激发或者有消息到来,此函数都可以返回。

    这样改过后,再发给客户测试,现象消失,问题解决。

  • WIN32获取当前程序所在目录

    WIN32获取当前程序所在目录

    #include <Shlwapi.h>
    #pragma comment (lib , "shlwapi.lib" )
    
    TCHAR wszModulePath[MAX_PATH ];
    ::memset(wszModulePath, 0, sizeof(TCHAR)*MAX_PATH);
    GetModuleFileName(NULL , wszModulePath, MAX_PATH);
    PathAppend(wszModulePath, _T ("..\\" ));
    wcscat_s(wszModulePath, GAME_CLIENT_PATH);

  • WIN32获取公网IP

    WIN32获取公网IP的代码:

    Utility.h

    #pragma once
    class CUtility
    {
    public:
           CUtility();
           ~CUtility();
    
    public:
            DWORD HttpGet( LPCTSTR lpszFullUrl, char *pBuffer, int iBufferSize);
            void GetPublicIp( TCHAR *pIP, int len);
    };

    Utility.cpp

    #include "stdafx.h"
    #include "Utility.h"
    #include "Transcode.h"
    #include<wininet.h>
    #pragma comment (lib ,"wininet.lib" )  
    
    
    CUtility::CUtility()
    {
    }
    
    
    CUtility::~CUtility()
    {
    }
    
    void CUtility ::GetPublicIp(TCHAR *pIP, int len)
    {
            char szBuffer[1024];
           memset(szBuffer, 0, sizeof( char) * 1024);
           HttpGet( _TEXT( "http://city.ip138.com/ip2city.asp" ), szBuffer, 1024);
    
            char* begin = strstr(szBuffer, "[")+1;
            char* end = strstr(begin, "]");
            int offset = end - begin;
           begin[offset] = '\0';
            char *ip = begin;
    
           std:: wstring wip;
            Transcode::ANSI_to_Unicode(ip, offset, wip);
           
           wcsncpy_s( pIP, len, wip.c_str(), offset);
    }
    
    DWORD CUtility ::HttpGet(LPCTSTR lpszFullUrl, char *pBuffer, int iBufferSize)
    {
            if ( lpszFullUrl == NULL )
                   return 0;
    
            HINTERNET hNet = :: InternetOpen(_TEXT ("Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0"),
                   PRE_CONFIG_INTERNET_ACCESS,
                   NULL,
                   INTERNET_INVALID_PORT_NUMBER,
                  0);
            if (hNet == NULL)
           {
                   //TRACE(_T("error: InternetOpen发生异常. 错误代号: %s; 文件: %s; 行: %d/n"), ::GetLastError(), __FILE__, __LINE__);
                   return 0;
           }
    
            HINTERNET hUrlFile = :: InternetOpenUrl(hNet,
                   lpszFullUrl,
                   NULL,
                  0,
                   INTERNET_FLAG_RELOAD,
                  0);
    
            if (!hUrlFile)
           {
                   //TRACE(_T("error:InternetOpenUrl发生异常. 错误代号: %s; 您可能需要添加\"Http://\" 或 \"Ftp://\" 文件: %s; 行: %d/n"), ::GetLastError(), __FILE__, __LINE__);
                   return 0;
           }
    
           ::memset( pBuffer, 0, iBufferSize);
            DWORD dwBytesRead = 0;
            char szTemp[1024] = { 0 };
            DWORD dwTotalReadBytes = 0;
            while (InternetReadFile(hUrlFile, szTemp, sizeof(szTemp) - 1, &dwBytesRead))
           {
                   if (0 == dwBytesRead)
                          break;
                  szTemp[dwBytesRead] = 0; //此处非常重要,缺了这一句可能抓的内容就不正确
    
                   // 缓冲区大小不够时,停止向目的缓冲区复制数据,跳出
                   if (dwTotalReadBytes + dwBytesRead >= ( UINT) iBufferSize)
                  {
                          pBuffer[ iBufferSize - 1] = 0;
                          break;
                  }
    
                  strcat_s( pBuffer, 1024, szTemp);
                   ZeroMemory(szTemp, sizeof (szTemp));
    
                  dwTotalReadBytes += dwBytesRead;
    
           }
    
           ::InternetCloseHandle(hUrlFile);
           ::InternetCloseHandle(hNet);
            return dwTotalReadBytes;
    }
    

  • MFC中去掉窗口类型为Overlapped的标题栏

    MFC中去掉窗口类型为Overlapped的标题栏

    ModifyStyle(WS_CAPTION, NULL, SWP_DRAWFRAME);

  • 禁止WIN32系统关机

    建立MFC程序,截获WM_QUERYENDSESSION消息,响应ON_WM_QUERYENDSESSION() ,消息响应函数对应为:   afx_msg BOOL OnQueryEndSession();  直接在该函数中return false 则拒绝了Windows的WM_QUERYENDSESSION的请求,Windows则无法正常软关机。(开始->关闭计算机->关机、注销、重启)。

    Windows在关机的时候会向所有顶层窗口广播一个消息WM_QUERYENDSESSION,应该不是所有进程,而是已经注册窗口类的程序。所以控制台程序不接收WM_QUERYENDSESSION消息。

  • ShellExecute不能执行批处理文件

    ShellExecute不能执行批处理文件,以下是解决办法:

    以下代码怎么都不执行a.bat,最后通过WinExec("./a.bat", SW_SHOW);解决

    ShellExecute(NULL, "open", "./a.bat", NULL, NULL, SW_SHOW);

  • GetStartupInfo 函数

    GetStartupInfo 函数
    当被调用的进程创建时, 用于返回STARTUPINFO结构的内容

    说明
    CreateProcess前,要调用这函数,获取要创建进程的信息
    否则,会出现创建进程直接崩溃,没有提示信息

  • 关于gethostname函数失败的问题

    调用gethostname函数失败。

    解决办法:调用gethostname之前, 要先调用WSAStartup才可以, 否则gethostname会失败!

    下面是正确的代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <Winsock2.h>
    #include <windows.h>
    #pragma comment(lib, "Ws2_32")
    int main()
    {
    	WSADATA wsData;
    	::WSAStartup(MAKEWORD(2,2), &wsData);
    	char szIP[32] = {0};
    	char szHostName[32] = {0};
    	int iResult = ::gethostname(szHostName, sizeof(szHostName));
    	if (iResult != 0)
    	{
    		printf("error/n");
    		return -1;
    	}
    	printf("%s/n", szHostName);
    	hostent *pHost = ::gethostbyname(szHostName);
    	::WSACleanup();
    	return 0;
    } 
  • Win32编程,让DC不重画某个区域的API函数

    Win32编程,让DC不重画某个区域的API函数:ExcludeClipRect

    描述:这个函数将创建一个新的区域,这个新的区域 由 现有的区域 去掉 指定区域 后 组成。

    功能:可以让DC不刷新某个指定区域。

    说明:这个函数在MFC中的CDC类里有封装。

    int ExcludeClipRect(
        HDC hdc, // handle to DC
        int nLeftRect, // x-coord of upper-left corner
        int nTopRect, // y-coord of upper-left corner
        int nRightRect, // x-coord of lower-right corner
        int nBottomRect // y-coord of lower-right corner
    );