MFC之picture控件滚动条的实现

直接上主要代码啦


// Image1Dlg.h : 头文件
//

#pragma once
#include "afxwin.h"

// CImage1Dlg 对话框
class CImage1Dlg : public CDialogEx
{
// 构造
public:
    CImage1Dlg(CWnd* pParent = NULL);   // 标准构造函数

// 对话框数据
    enum { IDD = IDD_IMAGE1_DIALOG };

    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持


// 实现
protected:
    HICON m_hIcon;

    // 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()

private:
    CString m_strFilePath;
    //定义图像文件信息
    //BITMAPINFOHEADER bi;//信息头
    //RGBQUAD* quad;//调色板
    //BYTE* lpBuf;//图像数据
    //BITMAPINFO* pbi;
    //int flag; //标志,表示是否打开了bmp文件
    //int numQuad; //调色板数目
    //BYTE* lpShowBuf;//用于显示的图像数据
    //int zoomFactor;//缩放比率

    CImage m_pic;             //载入的图片
    CDC m_cacheDC;           //缓冲DC
    CDC* m_picDC;             //picture control的DC
    CBitmap m_cacheBitmap;  //缓冲位图

    CRect m_client;//picture control大小
    int m_iFirst;

    int m_picWidth;    //载入图片的宽
    int m_picHeight;   //载入图片的高

    int m_iShowWidth;   //要显示的宽
    int m_iShowHeight;   //要显示的高

    int m_iX;    //图较大时要显示的X坐标
    int m_iY;    //图较大时要显示的Y坐标

public:
    CStatic m_PictureControl;//picture control 控件变量
    CScrollBar m_ScrollBarH; //水平滚动条
    CScrollBar m_ScrollBarV; //垂直滚动条
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnBnClickedButtonOpen();
    afx_msg void OnBnClickedOk();
};

// FullScreenDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "FullScreen.h"
#include "FullScreenDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define WIDTHBYTES(bits) (((bits)+31)/32*4)//用于使图像宽度所占字节数为4byte的倍数 



// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
 class CAboutDlg : public CDialogEx { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP() // CFullScreenDlg 对话框 CFullScreenDlg::CFullScreenDlg(CWnd* pParent /*=NULL*/) : CDialogEx(CFullScreenDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CFullScreenDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CFullScreenDlg, CDialogEx) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_LBUTTONDBLCLK() ON_WM_GETMINMAXINFO() END_MESSAGE_MAP() // CFullScreenDlg 消息处理程序 BOOL CFullScreenDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CFullScreenDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialogEx::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CFullScreenDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { char *filename = "1.jpg";//图像路径 IplImage* img = cvLoadImage(filename); drawpic(img, IDC_STATIC_PICSHOW);//IDC_STATIC_SHOWPicture Control 控件的ID cvReleaseImage(&img); CDialogEx::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标 //显示。 HCURSOR CFullScreenDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CFullScreenDlg::drawpic(IplImage* img, unsigned int id)//CShowPictureInFullScreenDlg 为对话框类名 { BYTE *g_pBits; HDC g_hMemDC; HBITMAP g_hBmp, g_hOldBmp; CDC *pDC; CStatic *pic; int width, height; CRect rect; pDC = GetDlgItem(id)->GetDC(); pic = (CStatic*)GetDlgItem(id); pic->GetClientRect(&rect); width = rect.Width(); height = rect.Height(); g_hMemDC = ::CreateCompatibleDC(pDC->m_hDC);//创建兼容DC BYTE bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)]; memset(bmibuf, 0, sizeof(bmibuf)); BITMAPINFO *pbmi = (BITMAPINFO*)bmibuf; pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = img->width; pbmi->bmiHeader.biHeight = img->height; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = 24; pbmi->bmiHeader.biCompression = BI_RGB; g_hBmp = ::CreateDIBSection(g_hMemDC, pbmi, DIB_RGB_COLORS, (void**)&g_pBits, 0, 0);//创建应用程序可以直接写入的、与设备无关的位图(DIB) g_hOldBmp = (HBITMAP)::SelectObject(g_hMemDC, g_hBmp);//复原兼容DC数据 BitBlt(g_hMemDC, 0, 0, width, height, pDC->m_hDC, 0, 0, SRCCOPY); //修改图像内容:g_pBits int l_width = WIDTHBYTES(img->width* pbmi->bmiHeader.biBitCount); for (int row = 0; row < img->height; row++) memcpy(&g_pBits[row*l_width], &img->imageData[(img->height - row - 1)*l_width], l_width); TransparentBlt(pDC->m_hDC, 0, 0, width, height, g_hMemDC, 0, 0, img->width, img->height, RGB(0, 0, 0)); SelectObject(g_hMemDC, g_hOldBmp); //释放内存资源 ReleaseDC(pDC); DeleteDC(g_hMemDC); DeleteObject(pic); DeleteObject(g_hBmp); DeleteObject(g_hOldBmp); } void CFullScreenDlg::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (!bFullScreen) { bFullScreen = true; //获取系统屏幕宽高 int g_iCurScreenWidth = GetSystemMetrics(SM_CXSCREEN); int g_iCurScreenHeight = GetSystemMetrics(SM_CYSCREEN); //用m_struOldWndpl得到当前窗口的显示状态和窗体位置,以供退出全屏后使用 GetWindowPlacement(&m_struOldWndpl); GetDlgItem(IDC_STATIC_PICSHOW)->GetWindowPlacement(&m_struOldWndpPic); //计算出窗口全屏显示客户端所应该设置的窗口大小,主要为了将不需要显示的窗体边框等部分排除在屏幕外 CRect rectWholeDlg; CRect rectClient; GetWindowRect(&rectWholeDlg);//得到当前窗体的总的相对于屏幕的坐标 RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery, &rectClient);//得到客户区窗口坐标 ClientToScreen(&rectClient);//将客户区相对窗体的坐标转为相对屏幕坐标 //GetDlgItem(IDC_STATIC_PICSHOW)->GetWindowRect(rectClient);//得到PICTURE控件坐标 rectFullScreen.left = rectWholeDlg.left - rectClient.left; rectFullScreen.top = rectWholeDlg.top - rectClient.top; rectFullScreen.right = rectWholeDlg.right + g_iCurScreenWidth - rectClient.right; rectFullScreen.bottom = rectWholeDlg.bottom + g_iCurScreenHeight - rectClient.bottom; //设置窗口对象参数,为全屏做好准备并进入全屏状态 WINDOWPLACEMENT struWndpl; struWndpl.length = sizeof(WINDOWPLACEMENT); struWndpl.flags = 0; struWndpl.showCmd = SW_SHOWNORMAL; struWndpl.rcNormalPosition = rectFullScreen; SetWindowPlacement(&struWndpl);//该函数设置指定窗口的显示状态和显示大小位置等,是我们该程序最为重要的函数 //将PICTURE控件的坐标设为全屏大小 GetDlgItem(IDC_STATIC_PICSHOW)->MoveWindow(CRect(0, 0, g_iCurScreenWidth, g_iCurScreenHeight)); } else { GetDlgItem(IDC_STATIC_PICSHOW)->SetWindowPlacement(&m_struOldWndpPic); SetWindowPlacement(&m_struOldWndpl); bFullScreen = false; } CDialogEx::OnLButtonDblClk(nFlags, point); } void CFullScreenDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (bFullScreen) { lpMMI->ptMaxSize.x = rectFullScreen.Width(); lpMMI->ptMaxSize.y = rectFullScreen.Height(); lpMMI->ptMaxPosition.x = rectFullScreen.left; lpMMI->ptMaxPosition.y = rectFullScreen.top; lpMMI->ptMaxTrackSize.x = rectFullScreen.Width(); lpMMI->ptMaxTrackSize.y = rectFullScreen.Height(); } CDialogEx::OnGetMinMaxInfo(lpMMI); } 

你可能感兴趣的:(mfc,控件,对话框)