标签归档:MFC

MFC 打印图片

BOOL PrintBitmap(LPCTSTR filename)
{
    CPrintDialog printDlg(FALSE);
    // printDlg.GetDefaults();

    if (printDlg.DoModal() == IDCANCEL)
        return FALSE;

    CDC dc;
    if (!dc.Attach(printDlg.GetPrinterDC()))
    {
        AfxMessageBox(_T("未发现发打印设备"));
        return FALSE;
    }

    dc.m_bPrinting = TRUE;
    DOCINFO di;
    // 初始化打印信息
    ::ZeroMemory(&di, sizeof(DOCINFO));
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = filename;
    BOOL bPrintingOK = dc.StartDoc(&di); // 开始打印

    CPrintInfo Info;
    Info.SetMaxPage(1); // 只打印一页
    int maxw = dc.GetDeviceCaps(HORZRES);
    int maxh = dc.GetDeviceCaps(VERTRES);
    Info.m_rectDraw.SetRect(0, 0, maxw, maxh);
    for (UINT page = Info.GetMinPage(); page <=Info.GetMaxPage() && bPrintingOK; page++)
    {
        dc.StartPage(); // 开始打印新的一页
        Info.m_nCurPage = page;
        CBitmap bitmap;

        // 加载位图
        if (!bitmap.Attach(::LoadImage(::GetModuleHandle(NULL), filename, IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE)))
        {
            AfxMessageBox(_T("位图加载失败!"));
            return FALSE;
        }
        BITMAP bm;
        bitmap.GetBitmap(&bm);
        int w = bm.bmWidth;
        int h = bm.bmHeight;
        // 创建内存设备上下文
        CDC memDC;
        memDC.CreateCompatibleDC(&dc);
        CBitmap *pBmp = memDC.SelectObject(&bitmap);
        memDC.SetMapMode(dc.GetMapMode());
        dc.SetStretchBltMode(HALFTONE);
        // 拉伸打印
        dc.StretchBlt(0, 0, maxw, maxh, &memDC, 0, 0, w, h, SRCCOPY);
        // clean up
        memDC.SelectObject(pBmp);
        // end page
        bPrintingOK = (dc.EndPage() > 0);
    }
    if (bPrintingOK)
        dc.EndDoc(); // 打印完成
    else

        dc.AbortDoc(); // 终止打印

    return TRUE;
}

void CPrintDemoDlg::OnBnClickedOk()
{
    BOOL bRet = PrintBitmap(_T("1.bmp"));

    if (bRet)
        AfxMessageBox(_T("打印完成"));
}

VC++获取控制台命令的输出结果

#include "stdafx.h"

#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;

BOOL ExecDosCmd(string cmd, string &output)
{
    SECURITY_ATTRIBUTES sa;
    HANDLE hRead, hWrite;

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&hRead, &hWrite, &sa, 0))
    {
        return FALSE;
    }
    char command[1024]; // 长达1K的命令行,够用了吧
    strcpy(command, "Cmd.exe /C ");
    strcat(command, cmd.c_str());
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    si.cb = sizeof(STARTUPINFO);
    GetStartupInfo(&si);
    si.hStdError = hWrite;  // 把创建进程的标准错误输出重定向到管道输入
    si.hStdOutput = hWrite; // 把创建进程的标准输出重定向到管道输入
    si.wShowWindow = SW_HIDE;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    // 关键步骤,CreateProcess函数参数意义请查阅MSDN
    if (!CreateProcess(NULL, command, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
    {
        CloseHandle(hWrite);
        CloseHandle(hRead);
        return FALSE;
    }
    CloseHandle(hWrite);

    char buffer[4096] = {0}; // 用4K的空间来存储输出的内容,只要不是显示文件内容,一般情况下是够用了。
    DWORD bytesRead;
    while (true)
    {
        if (ReadFile(hRead, buffer, 4095, &bytesRead, NULL) == NULL)
            break;
        // buffer中就是执行的结果,可以保存到文本,也可以直接输出
        // AfxMessageBox(buffer);   //这里是弹出对话框显示
        // cout << "----:" << endl << buffer << endl;
    }
    CloseHandle(hRead);

    output = buffer;
    return TRUE;
}

int main()
{
    string output;
    ExecDosCmd("wmic diskdrive get Caption,SerialNumber", output);
    cout << output << endl;
    return 0;
}

MFC通过wininet下载文件

// down.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <windows.h> 
#include <wininet.h>   
#include <string> 
#include <iostream>
#include <vector>
using namespace std; 
#pragma comment(lib, "wininet.lib") 




 
//下载 
#define  DOWNHELPER_AGENTNAME         "down" 
#define  LEN_OF_BUFFER_FOR_QUERYINFO  128 
#define  DOWNLOAD_BUF_SIZE            (10*1024)  //10KB 
#define  MAX_DOWNLOAD_REQUEST_TIME    10   
#define  MAX_DOWNLOAD_BYTESIZE        (1000*1024*1024) //1000MB 
 
 
BOOL _TryHttpSendRequest(LPVOID hRequest, int nMaxTryTimes); //多次发送请求函数 
 
//HTTP下载函数,通过先请求HEAD的方式然后GET,可以通过HEAD对下载的文件类型和大小做限制 
BOOL DownloadUrl(std::string strUrl, std::string strFileName) 
{ 
    BOOL bRet = FALSE; 
    if (strUrl == "" || strFileName == "") 
        return FALSE; 
 
    //定义变量 
    HINTERNET hInet = NULL; //打开internet连接handle 
    HINTERNET hConnect = NULL; //HTTP连接 
    HINTERNET hRequestHead = NULL; //HTTP Request 
    HINTERNET hRequestGet = NULL; //HTTP Request 
    HANDLE hFileWrite = NULL; //写文件的句柄 
    char* pBuf = NULL; //缓冲区 
    DWORD dwRequestTryTimes = MAX_DOWNLOAD_REQUEST_TIME; //尝试请求的次数 
    DWORD dwDownBytes = 0; //每次下载的大小 
    DWORD dwDownFileTotalBytes = 0; //下载的文件总大小 
    DWORD dwWriteBytes = 0; //写入文件的大小 
    char bufQueryInfo[LEN_OF_BUFFER_FOR_QUERYINFO] = {0}; //用来查询信息的buffer 
    DWORD dwBufQueryInfoSize = sizeof(bufQueryInfo); 
    DWORD dwStatusCode = 0; 
    DWORD dwContentLen = 0; 
    DWORD dwSizeDW = sizeof(DWORD); 
 
    //分割URL 
    CHAR pszHostName[INTERNET_MAX_HOST_NAME_LENGTH] = {0}; 
    CHAR pszUserName[INTERNET_MAX_USER_NAME_LENGTH] = {0}; 
    CHAR pszPassword[INTERNET_MAX_PASSWORD_LENGTH] = {0}; 
    CHAR pszURLPath[INTERNET_MAX_URL_LENGTH] = {0}; 
    CHAR szURL[INTERNET_MAX_URL_LENGTH] = {0}; 
    URL_COMPONENTSA urlComponents = {0}; 
    urlComponents.dwStructSize = sizeof(URL_COMPONENTSA); 
    urlComponents.lpszHostName = pszHostName; 
    urlComponents.dwHostNameLength = INTERNET_MAX_HOST_NAME_LENGTH; 
    urlComponents.lpszUserName = pszUserName; 
    urlComponents.dwUserNameLength = INTERNET_MAX_USER_NAME_LENGTH; 
    urlComponents.lpszPassword = pszPassword; 
    urlComponents.dwPasswordLength = INTERNET_MAX_PASSWORD_LENGTH; 
    urlComponents.lpszUrlPath = pszURLPath; 
    urlComponents.dwUrlPathLength = INTERNET_MAX_URL_LENGTH; 
 
    bRet = InternetCrackUrlA(strUrl.c_str(), 0, NULL, &urlComponents); 
    bRet = (bRet && urlComponents.nScheme == INTERNET_SERVICE_HTTP); 
    if (!bRet) 
    { 
        goto _END_OF_DOWNLOADURL; 
    } 
     
    //打开一个internet连接 
    hInet = InternetOpenA(DOWNHELPER_AGENTNAME, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, NULL); 
    if (!hInet) 
    { 
        bRet = FALSE; 
        goto _END_OF_DOWNLOADURL; 
    } 
     
    //打开HTTP连接 
    hConnect = InternetConnectA(hInet, pszHostName, urlComponents.nPort, pszUserName, pszPassword, INTERNET_SERVICE_HTTP, 0, NULL); 
    if (!hConnect) 
    { 
        bRet = FALSE; 
        goto _END_OF_DOWNLOADURL; 
    } 
     
    //创建HTTP request句柄 
    if (urlComponents.dwUrlPathLength !=  0) 
        strcpy(szURL, urlComponents.lpszUrlPath); 
    else 
        strcpy(szURL, "/"); 
     
    //请求HEAD,通过HEAD获得文件大小及类型进行校验 
    hRequestHead = HttpOpenRequestA(hConnect, "HEAD", szURL, "HTTP/1.1", "", NULL, INTERNET_FLAG_RELOAD, 0); 
    bRet = _TryHttpSendRequest(hRequestHead, dwRequestTryTimes); 
    if (!bRet) 
    { 
        goto _END_OF_DOWNLOADURL; //请求HEAD失败 
    } 
    
    //查询content-length大小 
    dwContentLen = 0; 
    dwSizeDW = sizeof(DWORD); 
    bRet = HttpQueryInfo(hRequestHead, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_CONTENT_LENGTH, &dwContentLen, &dwSizeDW, NULL); 
    if (bRet) 
    { 
        //检查是否文件过大 
        if (dwContentLen > MAX_DOWNLOAD_BYTESIZE) 
        { 
            bRet = FALSE; 
            goto _END_OF_DOWNLOADURL; 
        } 
    } 
 
    //校验完成后再请求GET,下载文件 
    hRequestGet = HttpOpenRequestA(hConnect, "GET", szURL, "HTTP/1.1", "", NULL, INTERNET_FLAG_RELOAD, 0); 
    bRet = _TryHttpSendRequest(hRequestGet, dwRequestTryTimes); 
    if (!bRet) 
    { 
        goto _END_OF_DOWNLOADURL; //请求HEAD失败 
    } 
 
    //创建文件 
    hFileWrite = CreateFileA(strFileName.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    if (INVALID_HANDLE_VALUE == hFileWrite) 
    { 
        bRet = FALSE; 
        goto _END_OF_DOWNLOADURL; 
    } 
 
    //分配缓冲 
    pBuf = new char[DOWNLOAD_BUF_SIZE]; //分配内存 
    if (!pBuf) 
    { 
        bRet = FALSE; 
        goto _END_OF_DOWNLOADURL; 
    } 
 
    //多次尝试下载文件 
    dwDownFileTotalBytes = 0; 
    while (1) 
    { 
        dwDownBytes = 0; 
        memset(pBuf, 0, DOWNLOAD_BUF_SIZE*sizeof(char)); 
        bRet = InternetReadFile(hRequestGet, pBuf, DOWNLOAD_BUF_SIZE, &dwDownBytes); 
        if (bRet) 
        { 
            if (dwDownBytes > 0) 
            { 
                dwDownFileTotalBytes += dwDownBytes; 
                bRet = WriteFile(hFileWrite, pBuf, dwDownBytes, &dwWriteBytes, NULL); //写入文件 
                if (!bRet) 
                { 
                    goto _END_OF_DOWNLOADURL; 
                } 
            } 
            else if (0 == dwDownBytes) 
            { 
                bRet = TRUE; 
                break; //下载成功完成 
            } 
        } 
    } 
     
    //清理 
_END_OF_DOWNLOADURL: 
    if (INVALID_HANDLE_VALUE != hFileWrite) 
        CloseHandle(hFileWrite); 
    if (pBuf) 
        delete [] pBuf; 
    if (hRequestGet) 
        InternetCloseHandle(hRequestGet); 
    if (hRequestHead) 
        InternetCloseHandle(hRequestHead); 
    if (hConnect) 
        InternetCloseHandle(hConnect); 
    if (hInet) 
        InternetCloseHandle(hInet); 
     
    return bRet; 
} 
 
//多次发送请求函数 
BOOL _TryHttpSendRequest(LPVOID hRequest, int nMaxTryTimes) 
{ 
    BOOL bRet = FALSE; 
    DWORD dwStatusCode = 0; 
    DWORD dwSizeDW = sizeof(DWORD); 
    while (hRequest && (nMaxTryTimes-- > 0)) //多次尝试发送请求 
    { 
        //发送请求 
        bRet = HttpSendRequestA(hRequest, NULL, 0, NULL, 0); 
        if (!bRet) 
        { 
            continue; 
        } 
        else 
        { 
            //判断HTTP返回的状态码 
            dwStatusCode = 0; 
            dwSizeDW = sizeof(DWORD); 
            bRet = HttpQueryInfo(hRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &dwStatusCode, &dwSizeDW, NULL); 
            if (bRet) 
            { 
                //检查状态码 
                if (HTTP_STATUS_OK == dwStatusCode) //200 OK 
                { 
                    break; 
                } 
                else 
                { 
                    bRet = FALSE; 
                    continue; 
                } 
            } 
        } 
    } 
 
    return bRet; 
} 
 

//////////////////////////////////////////////////////////////////////////

BOOL HttpGet(string url, string &result)
{
     vector<char> v; 
    const CHAR * szUrl = url.c_str(); 
    CHAR szAgent[] = ""; 
    HINTERNET hInternet1 =  
        InternetOpen(NULL,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,NULL); 
    if (NULL == hInternet1) 
     { 
        InternetCloseHandle(hInternet1); 
        return FALSE; 
     } 
    HINTERNET hInternet2 =  
        InternetOpenUrl(hInternet1,szUrl,NULL,NULL,INTERNET_FLAG_NO_CACHE_WRITE,NULL); 
    if (NULL == hInternet2) 
     { 
        InternetCloseHandle(hInternet2); 
        InternetCloseHandle(hInternet1); 
        return FALSE; 
     } 
    DWORD dwMaxDataLength = 500; 
    PBYTE pBuf = (PBYTE)malloc(dwMaxDataLength*sizeof(TCHAR)); 
    if (NULL == pBuf) 
     { 
        InternetCloseHandle(hInternet2); 
        InternetCloseHandle(hInternet1); 
        return FALSE; 
     } 
    DWORD dwReadDataLength = NULL; 
    BOOL bRet = TRUE; 
    do  
    { 
        ZeroMemory(pBuf,dwMaxDataLength*sizeof(TCHAR)); 
        bRet = InternetReadFile(hInternet2,pBuf,dwMaxDataLength,&dwReadDataLength); 
        for (DWORD dw = 0;dw < dwReadDataLength;dw++) 
          { 
            v.push_back(pBuf[dw]); 
          } 
     } while (NULL != dwReadDataLength); 

    vector<char>::iterator i; 
    for(i=v.begin(); i!=v.end(); i++) 
        result += *i;

     return TRUE;
}

//////////////////////////////////////////////////////////////////////////
 
/*
int main(int argc, char* argv[]) 
{ 
    cout << "正在下载..."; 
    BOOL bR = DownloadUrl("http://42.duote.com.cn/office2007.zip", "test.zip"); 
    if (bR) 
        cout << "完成" << endl; 
    else 
        cout << "失败" << endl; 
    return 0; 
}
*/


string trim(const string& str)
{
     string::size_type pos = str.find_first_not_of(' ');
     if (pos == string::npos)
     {
          return str;
     }
     string::size_type pos2 = str.find_last_not_of(' ');
     if (pos2 != string::npos)
     {
          return str.substr(pos, pos2 - pos + 1);
     }
     return str.substr(pos);
}

int split(const string& str, vector<string>& ret_, string sep = ",")
{
     if (str.empty())
     {
          return 0;
     }
    
     string tmp;
     string::size_type pos_begin = str.find_first_not_of(sep);
     string::size_type comma_pos = 0;
    
     while (pos_begin != string::npos)
     {
          comma_pos = str.find(sep, pos_begin);
          if (comma_pos != string::npos)
          {
               tmp = str.substr(pos_begin, comma_pos - pos_begin);
               pos_begin = comma_pos + sep.length();
          }
          else
          {
               tmp = str.substr(pos_begin);
               pos_begin = comma_pos;
          }
         
          if (!tmp.empty())
          {
               ret_.push_back(tmp);
               tmp = "";
          }
     }
     return 0;
}

string replace(const string& str, const string& src, const string& dest)
{
     string ret;
    
     string::size_type pos_begin = 0;
     string::size_type pos       = str.find(src);
     while (pos != string::npos)
     {
          cout <<"replacexxx:" << pos_begin <<" " << pos <<"\n";
          ret.append(str.data() + pos_begin, pos - pos_begin);
          ret += dest;
          pos_begin = pos + 1;
          pos       = str.find(src, pos_begin);
     }
     if (pos_begin < str.length())
     {
          ret.append(str.begin() + pos_begin, str.end());
     }
     return ret;
}

void Debug(string str)
{    
     MessageBox(NULL, str.c_str(), "DEBUG", MB_OK);
}


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
     string html;
     if (!HttpGet("http://42.96.190.81:81/list.txt", html))
     {
          MessageBox(NULL, "列表获取失败!", "ERROR", MB_OK);
          return 0;
     }
    

     vector<string> urls;
     split(html, urls, "\r\n");
     for(int i=0; i<urls.size(); i++)
     {
          size_t pos = urls[i].rfind('/', urls[i].size());
          string fileName = urls[i].substr(pos+1, urls[i].size()-pos-1);

          if (DownloadUrl(urls[i], fileName))
          {
               Debug(fileName + "下载成功");

          }

     }
     Debug("完成");



     return 0;
}


MFC中ToString()、Convert.ToString()、(string)、as string 的区别

通常 object 到 string 有四种方式(假设有object obj):obj.ToString()、Convert.ToString()、(string)obj、obj as string。他们都能将 object 对象转换成 string 对象。我就讲讲他们的异同以及在实际中应该使用哪个。

前两个方法通常是由别的对象得到 string 对象,它们间的区别只表现在要转换的对象为 null 时,如果 obj 为 null,调用 obj.ToString 方法会导致 NullReferenceException 异常,调用 Convert.ToString 不会抛出异常而返回一个 null。

用强制转换(string)obj 要求 obj 的运行时类型必须是 string。如果不是,就会抛出异常。

用 as 方法则会相对平稳,当 obj 的运行时类型不是 string 时会返回 null 而不抛出异常。

所以在通常在我们需要得到某个对象的 string 表达形式时,我们应该使用 ToString 和 Convert.ToString,这时候你就得根据情形选一个,假如你能保证你的对象不为 null,则两个差不多。如果有可能为null,你就应该用 Convert.ToString,如果你希望它为 null 的时候抛出异常,那么当然可以选择 ToString。

编者注:

这里是说 object 到 string,如果在其它类型上调用第一种 ToString(),得到的不一定是实际的内容,可能是对该类的描述,这取决于该类如何实现ToString() 方法

CHtmlView, 页面载入快播播放器时, 窗口关闭后, 出现内存访问失败的问题

如果遇到关闭带网页的窗口后,崩溃的问题,可以

  1. 打开about:blank空白页
  2. ShowWindow(SW_HIDE);
  3. SetTimer设置定时器,在定时器里关掉窗口

———– 解决页面嵌入快播播放器里,崩溃的问题 2011年9月25日 17时48分03秒

开发环境: VS2003

CHttpFile 获取URL重定向后的文件名

// 获取URL重定向后的文件名,如果没有重定向,也返回下载文件名
CString GetFileNameFromRedirectUrl(CString strUrl)
{
	CInternetSession iSession; 
	CStdioFile* pFileDown = NULL; 
	CString sFileName; 
 
	pFileDown = iSession.OpenURL(strUrl, 1, INTERNET_FLAG_TRANSFER_BINARY); 
 
	CHttpFile* pHttpFile = (CHttpFile *)pFileDown; 
	HINTERNET hHttpFile = HINTERNET(*pHttpFile); 
 
	//获得重定向文件名 
	BOOL bResult = pHttpFile->QueryOption(INTERNET_OPTION_URL, sFileName);
	int flag=sFileName.ReverseFind('/');
	CString strFileName=sFileName.Mid(flag+1);
 
	return strFileName;
}

VC 屏幕截图

void CScreenDlg::OnPaint()
{
	CClientDC dc(this); 
	// 获取屏幕DC
	HDC hScrDC = ::GetDC(NULL);
	// 得到屏幕分辨率  
	INT nHeight = GetDeviceCaps(hScrDC, VERTRES);
	INT nWidth = GetDeviceCaps(hScrDC, HORZRES);  
	// 创建屏幕DC的兼容DC
	HDC hMemDC1 = CreateCompatibleDC(hScrDC);
	// 创建屏幕兼容位图
	HBITMAP hBitmap1 = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
	// 把兼容位图选入兼容DC
	HBITMAP hBitmap2 = (HBITMAP)SelectObject(hMemDC1, hBitmap1);
	// 复制DC
	BitBlt(hMemDC1, 0, 0, nWidth, nHeight, hScrDC, 0, 0, SRCCOPY);
	// 显示
	BitBlt(dc.GetSafeHdc(), 0, 0, nHeight, nWidth, hMemDC1, 0, 0, SRCCOPY);
	::DeleteObject(hBitmap1);
	::DeleteDC(hMemDC1);
	__super::OnPaint();
}

VC++托盘图标菜单弹出后,点击其它地方,菜单不消失的问题

在TrackPopupMenu函数前面添加SetForegroundWindow();即可解决.

示例代码:

POINT point;
HMENU hMenu, hSubMenu;
GetCursorPos(&point);
hMenu = LoadMenu(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MENU1));
hSubMenu = GetSubMenu(hMenu, 0);
SetMenuDefaultItem(hSubMenu, -1, FALSE);
SetForegroundWindow();	// 解决托盘图标菜单弹出后,点击其它地方,菜单不消失的问题
TrackPopupMenu(hSubMenu, TPM_BOTTOMALIGN, point.x, point.y, 0, m_hWnd, NULL);
PostMessage(WM_NULL, 0, 0);   
DestroyMenu(hMenu);