VC 中用 IPicture 在窗口中显示图片文件



#include <windows.h>  // Windows SDK 要用到的   
#include <commdlg.h>  // 打开文件的窗口要包含这个头文件   
  
//用到了 IPicture 接口,要包含下面两个 头文件   
#include <ocidl.h>    
#include <olectl.h>    
  
// 声明窗口函数的原型   
LRESULT CALLBACK MainWndProc (HWND, UINT, WPARAM, LPARAM);   
  
// 声明显示图片的函数原型   
HRESULT ShowPic( char  *lpstrFile,HWND hWnd) ;   
  
//图片文件名   
char  lpstrFile[MAX_PATH]= "" ;   
  
  
int  WINAPI WinMain (HINSTANCE hThisInstance,   
                    HINSTANCE hPrevInstance,   
                    LPSTR lpszArgument,   
                     int  nFunsterStil)   
                       
{   
     // 窗口类名   
     char  szClassName[ ] =  "ShowPicture" ;   
       
    WNDCLASSEX windclass;   
       
     //用描述主窗口的参数填充 WNDCLASSEX 结构   
    windclass.cbSize =  sizeof (windclass);   //结构大小   
    windclass.hInstance = hThisInstance;    //实例句酚   
    windclass.lpszClassName = szClassName;   
    windclass.lpfnWndProc = MainWndProc;    //窗口函数指针   
    windclass.style = CS_DBLCLKS;           //捕获双击事件   
    windclass.cbSize =  sizeof  (WNDCLASSEX);   
       
    windclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);  //使用预定义图标   
    windclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);  //使用预定义类的小图标   
    windclass.hCursor = LoadCursor (NULL, IDC_ARROW);  //使用预定义光标   
    windclass.lpszMenuName = NULL;                  //不指定主菜单   
    windclass.cbClsExtra = 0;                       //没有额外的类内存   
    windclass.cbWndExtra = 0;                       //没有额外的窗口内存   
       
    windclass.hbrBackground = (HBRUSH) COLOR_BACKGROUND;  //使用预定义背景画刷   
       
     //注册这个窗口类,如果失败直接退出程序    
     if  (!RegisterClassEx (&windclass))   
         return  0;   
       
     //创建主窗口   
    HWND hWnd = CreateWindowEx (   
        0,                    //dwExStyle, 扩展样式   
        szClassName,          //lpClassName, 类名   
         "显示图片 -- 鼠标双击浏览图片文件      -- Author:Unmi" ,  //lpWindowName, 标题   
        WS_OVERLAPPEDWINDOW,  //dwStyle, 窗口风格   
        CW_USEDEFAULT,        //X, 初始 X 坐标   
        CW_USEDEFAULT,        //Y, 初始 YX 坐标   
        640,                  //nWidth, 宽度   
        480,                  //nHeight, 高度   
        HWND_DESKTOP,         //hWndParent, 父窗口句柄   
        NULL,                 //hMenu, 菜单句柄   
        hThisInstance,        //hInstance, 程序实例句柄   
        NULL                  //lpParam, 用户数据   
        );   
       
     //显示窗口,刷新窗口客户区   
    ShowWindow (hWnd, nFunsterStil);   
       
     // 从消息队列中取出消息,交给窗口函数处理   
     // 直到 GetMessage 取出的消息是 WM_QUIT,即FALSE,则结束消息循环   
    MSG messages;       
     while  (GetMessage (&messages, NULL, 0, 0))   
    {   
         //转换键盘消息,把虚拟键转换为字符消息   
        TranslateMessage(&messages);   
           
         //将消息发送到相应的窗口函数   
        DispatchMessage(&messages);   
    }   
       
     // GetMessage 返回 FALSE,程序结束 PostQuitMessage() 发出这一消息   
     return  messages.wParam;   
}   
  
  
// 窗口函数,消息由 DispatchMessage 派发   
LRESULT CALLBACK MainWndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)   
{   
     switch  (message)  //处理消息   
    {   
     case  WM_DESTROY:   
         //向消息队列投递一个 WM_QUIT 消息,促使 GetMessage 函数返回0,结束消息循环   
        PostQuitMessage (0);   
         break ;   
     case  WM_LBUTTONDBLCLK:   
        {   
            OPENFILENAME file = {0};   
            file.lStructSize =  sizeof (file);   
            file.lpstrTitle =  "请选择一个图片文件" ;   
            file.lpstrFile = lpstrFile;   
            file.nMaxFile = MAX_PATH;   
            file.lpstrFilter =  "Pictures(*.jpg,*.gif,*.bmp)\0*.jpg;*.gif;*.bmp\0\0" ;   
             if (::GetOpenFileName(&file))   
            {          
                 //清除原来的图像   
                HDC hdc=GetDC(hWnd);    
                RECT rect;   
                ::GetWindowRect(hWnd,&rect);   
                ::FillRect(hdc,&rect,(HBRUSH) COLOR_BACKGROUND);   
                   
                ::SendMessage(hWnd,WM_PAINT,NULL,NULL);   
            }   
        }   
         break ;   
     case  WM_PAINT:   
        ShowPic(lpstrFile,hWnd);   
         break ;   
     default :   
           
         //将我们不处理的消息交给系统 做默认处理   
         return  DefWindowProc (hWnd, message, wParam, lParam);   
    }   
       
     return  0;   
}   
  
// 显示图片,此文的重点之所在了, lpstrFile 为图片文件名,hWnd 为窗口句柄   
HRESULT ShowPic( char  *lpstrFile,HWND hWnd)    
{    
    HDC hDC_Temp=GetDC(hWnd);    
       
    IPicture *pPic;    
    IStream *pStm;    
       
    BOOL bResult;    
       
    HANDLE hFile=NULL;    
    DWORD dwFileSize,dwByteRead;    
       
     //打开图形文件    
    hFile=CreateFile(lpstrFile,GENERIC_READ,    
        FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);    
       
     if  (hFile!=INVALID_HANDLE_VALUE)    
    {    
        dwFileSize=GetFileSize(hFile,NULL); //获取文件字节数    
           
         if  (dwFileSize==0xFFFFFFFF)    
             return  E_FAIL;    
    }    
     else     
    {    
         return  E_FAIL;    
    }    
       
       
     //分配全局存储空间    
    HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);    
    LPVOID pvData = NULL;    
       
     if  (hGlobal == NULL)    
         return  E_FAIL;    
       
     if  ((pvData = GlobalLock(hGlobal)) == NULL) //锁定分配内存块    
         return  E_FAIL;    
       
    ReadFile(hFile,pvData,dwFileSize,&dwByteRead,NULL); //把文件读入内存缓冲区    
       
    GlobalUnlock(hGlobal);    
       
    CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);    
       
     //装入图形文件    
    bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,(LPVOID*)&pPic);    
       
     if (FAILED(bResult))    
         return  E_FAIL;    
       
    OLE_XSIZE_HIMETRIC hmWidth;  //图片的真实宽度, 单位为英寸   
    OLE_YSIZE_HIMETRIC hmHeight;  //图片的真实高度, 单位为英寸   
    pPic->get_Width(&hmWidth);    
    pPic->get_Height(&hmHeight);    
       
     //转换hmWidth和hmHeight为pixels距离,1英寸=25.4毫米   
     int  nWidth = MulDiv(hmWidth,GetDeviceCaps(hDC_Temp,LOGPIXELSX),2540);   
     int  nHeight = MulDiv(hmHeight,GetDeviceCaps(hDC_Temp,LOGPIXELSY),2540);   
       
     //将图形输出到屏幕上(有点像BitBlt)    
    bResult=pPic->Render(hDC_Temp,0,0,nWidth,nHeight,    
        0,hmHeight,hmWidth,-hmHeight,NULL);    
       
    pPic->Release();    
       
    CloseHandle(hFile); //关闭打开的文件    
       
     if  (SUCCEEDED(bResult))    
    {    
         return  S_OK;    
    }    
     else     
    {    
         return  E_FAIL;    
    }    

}


转自:http://wallimn.iteye.com/blog/327789

VC PICTURE控件的使用,如何加载背景图片2009年04月19日 星期日 15:02vc picture控件的分类总结: (一) 非动态显示图片(即图片先通过资源管理器载入,有一个固定ID) (二) 动态载入图片(即只需要在程序指定图片的路径即可载入) 为方便说明,我们已经建好一个基于对话框的工程,名为Ttest. 对话框类为CTestDlg (一) vc picture控件非动态载入图片. 方法1.先从最简单的开始,用picture 控件来实现. 步骤: 先在资源里Import一张图片,ID为IDB_BITMAP2 然后在对话框上添加一个picture控件,右键点击打开属性, 将type下拉框选择BITMAP,紧跟着下面就出现一个Image下拉框, 拉开就会看到所有已经载入好的图片, 选择你要的图片.运行程序即可看到. 方法2vc picture控件.通过背景图 同样如上,先载入一张图片,ID为IDB_BITMAP2 TestDlg.h CBrush m_brBk;//在public定义 TestDlg.cpp 在初始化函数OnInitDialog()加入: BOOL CTestDlg::OnInitDialog() { CDialog::OnInitDialog(); CBitmap bmp; bmp.LoadBitmap(IDB_BITMAP2); m_brBk.CreatePatternBrush(&bmp); bmp.DeleteObject(); return TRUE; // return TRUE unless you set the focus to a control } 在打开类向导,找到WM_CTLCOLOR消息,重载得对应函数OnCtlColor(),添加如下: HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if (pWnd == this) { return m_brBk; } return hbr; } (二) vc picture控件动态载入图片. 方法3 图像控件(本例用KoDak 图像编辑控件) 1. 首先应该保证系统有这个控件。注意,它不能单独使用,必须和其他几个控件(特别是Imgcmn.dll)一同使用。如果没有,从别的机器上copy过来即可。这几个文件是Imgadmin.ocx,Imgcmn.dll,Imgedit.ocx,Imgscan.ocx,Imgshl.dll,Imgthumb.ocx,Imgutil.dll,把它们copy到windows\system目录下,然后用regsvr32.exe将它们分别注册。 2. 打开工程,进入资源管理器,在对话框上单击右键,单击Insert Activex control… 选择Kodak图象编辑控件,大小任意。 3. 在对话框上选该控件,为其添加变量:m_ctrlPicture。。 4. 在BOOL CTestDlg::OnInitDialog()添加如下: BOOL CTestDlg::OnInitDialog() { CDialog::OnInitDialog(); m_ctrlPicture.SetImage("aa.jpg"); //保证图像在工程目录下,也可以写绝对路径 m_ctrlPicture.Display(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 编译运行就OK了,此种方法的好处就是可能针对多种图像格式. 方法4 vc picture控件通过CBitmap,HBITMAP,直接用OnPaint()绘制 首先在CTestDlg类声明一个变量: CBitmap m_bmp; 然后我们在对话框加入一个picture 标签,名为IDC_STATIC1 然后: BOOL CDisplayPic::OnInitDialog() { CDialog::OnInitDialog(); if( m_bmp.m_hObject != NULL )//判断 m_bmp.DeleteObject(); /////////载入图片 HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), "c:\\aaa.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); if( hbmp == NULL ) return FALSE; ///////////////////////该断程序用来取得加载的BMP的信息//////////////////////// m_bmp.Attach( hbmp ); DIBSECTION ds; BITMAPINFOHEADER &bminfo = ds.dsBmih; m_bmp.GetObject( sizeof(ds), &ds ); int cx=bminfo.biWidth; //得到图像宽度 int cy=bminfo.biHeight; //得到图像高度 /////////////////// //////////////////////////////// /////////////得到了图像的宽度和高度后,我们就可以对图像大小进行适应,即调整控件的大小,让它正好显示一张图片/////////////////////////// CRect rect; GetDlgItem(IDC_STATIC1)->GetWindowRect(&rect); ScreenToClient(&rect); GetDlgItem(IDC_STATIC1)->MoveWindow(rect.left,rect.top,cx,cy,true);//调整大小 return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } 图片加载成功了,标签大小也适应了,下面就是绘制绘制图像了,打开类向导,重载WM_PAINT消息 void CDisplayPic::OnPaint() { //////////////以下三种情况任选一种会是不同效果(只能一种存在)/////////// //CPaintDC dc(this); //若用此句,得到的是对话框的DC,图片将被绘制在对话框上. CPaintDC dc(GetDlgItem(IDC_STATIC1)); //用此句,得到picture控件的DC,图像将被绘制在控件上 // CDC dc; // dc.m_hDC=::GetDC(NULL); //若用此两句,得到的是屏幕的DC,图片将被绘制在屏幕上/////////////////////////////////////////////////////// CRect rcclient; GetDlgItem(IDC_STATIC1)->GetClientRect(&rcclient); CDC memdc; memdc.CreateCompatibleDC(&dc); CBitmap bitmap; bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height()); memdc.SelectObject( &bitmap ); CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0); CDC maskdc; maskdc.CreateCompatibleDC(&dc); CBitmap maskbitmap; maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL); maskdc.SelectObject( &maskbitmap ); maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top, SRCCOPY); CBrush brush; brush.CreatePatternBrush(&m_bmp); dc.FillRect(rcclient, &brush); dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc, rcclient.left, rcclient.top,SRCPAINT); brush.DeleteObject(); // Do not call CDialog::OnPaint() for painting messages }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值