yehao's Blog

VC使用IPicture显示网上图片(通过URL指定)

转自http://blog.csdn.net/wallimn/article/details/3068643

/************************************************************/
VC IPicture
显示网络图片 显示远程图片 显示URL指定的图片 
通过HTTP下载显示图片 显示网上广告图片
上面是我罗列的关键字,我找这个文章换了好几种关键字写法,才找到,
为了方便它人,我把关键字全部写上。
/************************************************************/
文章很不错,正好解决了我的问题。感谢作者。这是个用SDK(没有使用MFC)开发的程序。
如果对SDK开发方式不是很熟,只看ShowPic函数就以了。
  1. #include <windows.h>  // Windows SDK 要用到的   
  2. #include <commdlg.h>  // 打开文件的窗口要包含这个头文件   
  3.   
  4. //用到了 IPicture 接口,要包含下面两个 头文件   
  5. #include <ocidl.h>    
  6. #include <olectl.h>    
  7.   
  8. // 声明窗口函数的原型   
  9. LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);   
  10.   
  11. // 声明显示图片的函数原型   
  12. HRESULT ShowPic(char *lpstrFile,HWND hWnd) ;   
  13.   
  14. //图片文件名   
  15. char lpstrFile[MAX_PATH]="";   
  16.   
  17.   
  18. int WINAPI WinMain (HINSTANCE hThisInstance,   
  19.                     HINSTANCE hPrevInstance,   
  20.                     LPSTR lpszArgument,   
  21.                     int nFunsterStil)   
  22.                        
  23. {   
  24.     // 窗口类名   
  25.     char szClassName[ ] = "ShowPicture";   
  26.        
  27.     WNDCLASSEX windclass;   
  28.        
  29.     //用描述主窗口的参数填充 WNDCLASSEX 结构   
  30.     windclass.cbSize = sizeof(windclass);  //结构大小   
  31.     windclass.hInstance = hThisInstance;   //实例句酚   
  32.     windclass.lpszClassName = szClassName;   
  33.     windclass.lpfnWndProc = MainWndProc;   //窗口函数指针   
  34.     windclass.style = CS_DBLCLKS;          //捕获双击事件   
  35.     windclass.cbSize = sizeof (WNDCLASSEX);   
  36.        
  37.     windclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); //使用预定义图标   
  38.     windclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); //使用预定义类的小图标   
  39.     windclass.hCursor = LoadCursor (NULL, IDC_ARROW); //使用预定义光标   
  40.     windclass.lpszMenuName = NULL;                 //不指定主菜单   
  41.     windclass.cbClsExtra = 0;                      //没有额外的类内存   
  42.     windclass.cbWndExtra = 0;                      //没有额外的窗口内存   
  43.        
  44.     windclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND; //使用预定义背景画刷   
  45.        
  46.     //注册这个窗口类,如果失败直接退出程序    
  47.     if (!RegisterClassEx (&windclass))   
  48.         return 0;   
  49.        
  50.     //创建主窗口   
  51.     HWND hWnd = CreateWindowEx (   
  52.         0,                   //dwExStyle, 扩展样式   
  53.         szClassName,         //lpClassName, 类名   
  54.         "显示图片 -- 鼠标双击浏览图片文件      -- Author:Unmi", //lpWindowName, 标题   
  55.         WS_OVERLAPPEDWINDOW, //dwStyle, 窗口风格   
  56.         CW_USEDEFAULT,       //X, 初始 X 坐标   
  57.         CW_USEDEFAULT,       //Y, 初始 YX 坐标   
  58.         640,                 //nWidth, 宽度   
  59.         480,                 //nHeight, 高度   
  60.         HWND_DESKTOP,        //hWndParent, 父窗口句柄   
  61.         NULL,                //hMenu, 菜单句柄   
  62.         hThisInstance,       //hInstance, 程序实例句柄   
  63.         NULL                 //lpParam, 用户数据   
  64.         );   
  65.        
  66.     //显示窗口,刷新窗口客户区   
  67.     ShowWindow (hWnd, nFunsterStil);   
  68.        
  69.     // 从消息队列中取出消息,交给窗口函数处理   
  70.     // 直到 GetMessage 取出的消息是 WM_QUIT,即FALSE,则结束消息循环   
  71.     MSG messages;       
  72.     while (GetMessage (&messages, NULL, 0, 0))   
  73.     {   
  74.         //转换键盘消息,把虚拟键转换为字符消息   
  75.         TranslateMessage(&messages);   
  76.            
  77.         //将消息发送到相应的窗口函数   
  78.         DispatchMessage(&messages);   
  79.     }   
  80.        
  81.     // GetMessage 返回 FALSE,程序结束 PostQuitMessage() 发出这一消息   
  82.     return messages.wParam;   
  83. }   
  84.   
  85.   
  86. // 窗口函数,消息由 DispatchMessage 派发   
  87. LRESULT CALLBACK MainWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)   
  88. {   
  89.     switch (message) //处理消息   
  90.     {   
  91.     case WM_DESTROY:   
  92.         //向消息队列投递一个 WM_QUIT 消息,促使 GetMessage 函数返回0,结束消息循环   
  93.         PostQuitMessage (0);   
  94.         break;   
  95.     case WM_LBUTTONDBLCLK:   
  96.         {   
  97.             OPENFILENAME file = {0};   
  98.             file.lStructSize = sizeof(file);   
  99.             file.lpstrTitle = "请选择一个图片文件";   
  100.             file.lpstrFile = lpstrFile;   
  101.             file.nMaxFile = MAX_PATH;   
  102.             file.lpstrFilter = "Pictures(*.jpg,*.gif,*.bmp)/0*.jpg;*.gif;*.bmp/0/0";   
  103.             if(::GetOpenFileName(&file))   
  104.             {          
  105.                 //清除原来的图像   
  106.                 HDC hdc=GetDC(hWnd);    
  107.                 RECT rect;   
  108.                 ::GetWindowRect(hWnd,&rect);   
  109.                 ::FillRect(hdc,&rect,(HBRUSH) COLOR_BACKGROUND);   
  110.                    
  111.                 ::SendMessage(hWnd,WM_PAINT,NULL,NULL);   
  112.             }   
  113.         }   
  114.         break;   
  115.     case WM_PAINT:   
  116.         ShowPic(lpstrFile,hWnd);   
  117.         break;   
  118.     default:   
  119.            
  120.         //将我们不处理的消息交给系统 做默认处理   
  121.         return DefWindowProc (hWnd, message, wParam, lParam);   
  122.     }   
  123.        
  124.     return 0;   
  125. }   
  126. // 显示图片, lpstrImgUrl 为图片URL地址,hWnd 为窗口句柄      
  127. HRESULT Utils::ShowPic(char *lpstrImgUrl,HWND hWnd)       
  128. {       
  129.     HDC hDC_Temp=GetDC(hWnd);       
  130.        
  131.     IPicture *pPic;       
  132.     IStream *pStm;       
  133.        
  134.     BOOL bResult;       
  135.        
  136.     DWORD dwFileSize,dwByteRead;       
  137.        
  138.     //读取网页上图片文件,实际是个CHttpFile指针   
  139.     CInternetSession session("HttpClient");   
  140.     CFile* httpFile = (CFile*)session.OpenURL(lpstrImgUrl);   
  141.        
  142.     if (httpFile!=INVALID_HANDLE_VALUE)       
  143.     {       
  144.         dwFileSize=  httpFile->GetLength();//获取文件字节数       
  145.            
  146.         if (dwFileSize==0xFFFFFFFF)       
  147.             return E_FAIL;       
  148.     }       
  149.     else       
  150.     {       
  151.         return E_FAIL;       
  152.     }       
  153.        
  154.        
  155.     //分配全局存储空间       
  156.     HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);       
  157.     LPVOID pvData = NULL;       
  158.        
  159.     if (hGlobal == NULL)       
  160.         return E_FAIL;       
  161.        
  162.     if ((pvData = GlobalLock(hGlobal)) == NULL)//锁定分配内存块       
  163.         return E_FAIL;       
  164.        
  165.     //把文件读入内存缓冲区       
  166.     dwByteRead = httpFile->Read(pvData,dwFileSize);   
  167.        
  168.     GlobalUnlock(hGlobal);       
  169.        
  170.     CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);       
  171.        
  172.     //装入图形文件       
  173.     bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,(LPVOID*)&pPic);       
  174.        
  175.     if(FAILED(bResult))       
  176.         return E_FAIL;       
  177.        
  178.     OLE_XSIZE_HIMETRIC hmWidth; //图片的真实宽度, 单位为英寸      
  179.     OLE_YSIZE_HIMETRIC hmHeight; //图片的真实高度, 单位为英寸      
  180.     pPic->get_Width(&hmWidth);       
  181.     pPic->get_Height(&hmHeight);       
  182.        
  183.     //转换hmWidth和hmHeight为pixels距离,1英寸=25.4毫米      
  184.     int nWidth = MulDiv(hmWidth,GetDeviceCaps(hDC_Temp,LOGPIXELSX),2540);      
  185.     int nHeight = MulDiv(hmHeight,GetDeviceCaps(hDC_Temp,LOGPIXELSY),2540);      
  186.        
  187.     //将图形输出到屏幕上(有点像BitBlt)       
  188.     bResult=pPic->Render(hDC_Temp,0,0,nWidth,nHeight,       
  189.         0,hmHeight,hmWidth,-hmHeight,NULL);       
  190.        
  191.     pPic->Release();       
  192.        
  193.     httpFile->Close();//关闭打开的文件       
  194.        
  195.     if (SUCCEEDED(bResult))       
  196.     {       
  197.         return S_OK;       
  198.     }       
  199.     else       
  200.     {       
  201.         return E_FAIL;       
  202.     }       
  203. }   

补充说明:
  原文的程序是使用SDK方式开发的,可能会有些人不习惯,我使用MFC方式验证调试了一下,效果还不错。如需要源码的,请到http://wallimn.ys168.com(我的网络硬盘)下载。
  我的程序是个很简单的程序,没有考虑重绘、图片大小的处理等问题,仅体现编程思想及方法。

posted on 2014-07-11 15:36 厚积薄发 阅读(554) 评论(0)  编辑 收藏 引用 所属分类: Windows编程


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿

随笔分类

文章分类

文章档案

搜索

最新评论