• 实例开发-NX二次开发手动截图工具


    • 版本

    NX9+VS2012

    • 演示

     

    • 开发思路

    在UG项目中添加一个MFC对话框资源,然后设置MFC对话框的鼠标消息回调,获得截图区域,最后保存图片(截图这个功能在VC++中网上可以百度到现成的代码)

    • 开发步骤

    1.新建BlockUI对话框(此处匆匆带过,不做详细步骤)

     2.新建VS项目(此处匆匆带过,不做详细步骤)

     3.添加资源(dialog对话框)

     

     如下

     删除对话框上的确定和取消

    在对话框上点右键-属性(更改Border为None)

     4.为对话框添加类

     

     5.添加初始化对话框虚函数

     

     6.在ShotDlg.h里加头文件#include "Resource.h"

     出现上面这种问题,加头文件#include "Resource.h"就行了

     7.更改基类

    在ShotDlg.h和ShotDlg.cpp里全部改掉

     8.在UG的代码里添加如下的几个头文件

     编译成功,如果失败,根据错误提示,自己找问题

     9.去ShotDlg.h和ShotDlg.cpp添加截图代码

     头文件里定义变量

     源文件里加在构造函数里的代码

        start=captured=false;
        LIMITE = 5;
        CDC *pdc=GetDesktopWindow()->GetDC();
        dc.CreateCompatibleDC(pdc);
        int nx=GetSystemMetrics(SM_CXSCREEN);
        int ny=GetSystemMetrics(SM_CYSCREEN);
        bmp.CreateCompatibleBitmap(pdc,nx,ny);
        pold=dc.SelectObject(&bmp);
        dc.BitBlt(0,0,nx,ny,pdc,0,0,SRCCOPY);

    加在析构函数里的代码

        dc.SelectObject(pold);
        bmp.DeleteObject();
        dc.DeleteDC();    

    加在初始化里的代码

        this->ShowWindow(SW_SHOWMAXIMIZED);
        int nx=GetSystemMetrics(SM_CXSCREEN);
        int ny=GetSystemMetrics(SM_CYSCREEN);
        SetWindowPos(&wndTopMost,0,0,nx,ny,SWP_SHOWWINDOW);

    下面开始为对话框添加五个消息回调

     

     

     

     

     步骤如下

     

     

     开始往每个消息函数里写代码

    BOOL CShotDlg::OnEraseBkgnd(CDC* pDC)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
    
        int nx=GetSystemMetrics(SM_CXSCREEN);
        int ny=GetSystemMetrics(SM_CYSCREEN);
        BITMAP bm;
        bmp.GetBitmap(&bm);
        BOOL X=pDC->BitBlt(0,0,nx,ny,&dc,0,0,SRCCOPY);
        return X;    
    
        //return CDialog::OnEraseBkgnd(pDC);
    }
    void CShotDlg::OnLButtonDown(UINT nFlags, CPoint point)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        if(!start)
        {
            opt=point;lastmove=point;start=true;captured=false;
    
            CDC *pDC=GetDC();
            CPen pen(PS_SOLID,2,RGB(255,0,0));
            CPen *oldp=pDC->SelectObject(&pen);
            int nmode=pDC->SetROP2(R2_NOTXORPEN);
            pDC->Rectangle(point.x,point.y,point.x,point.y);
            nmode=pDC->SetROP2(nmode);
            pDC->SelectObject(oldp);
            ReleaseDC(pDC);
        }
        CDialog::OnLButtonDown(nFlags, point);
    }
    void CShotDlg::OnLButtonUp(UINT nFlags, CPoint point)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        if(start)
        {
            start=false;
            CDC *pDC=GetDC();
            CPen pen(PS_SOLID,2,RGB(255,0,0));
            CPen *oldp=pDC->SelectObject(&pen);
            int nmode=pDC->SetROP2(R2_NOTXORPEN);
            pDC->Rectangle(opt.x,opt.y,lastmove.x,lastmove.y);
            nmode=pDC->SetROP2(nmode);
            pDC->SelectObject(oldp);
            
            lastmove=point;
    
            int ox,oy,dx,dy;
            ox=(opt.x<point.x)?opt.x:point.x;
            oy=(opt.y<point.y)?opt.y:point.y;
            dx=(opt.x>point.x)?opt.x:point.x;
            dy=(opt.y>point.y)?opt.y:point.y;
            
            if(dx-ox>LIMITE&&dy-oy>LIMITE)
            {
                captured=true;ReleaseDC(pDC);    
                OnOK();
            }
            else
            {
                captured=false;ReleaseDC(pDC);OnCancel();
            }                    
        }
        CDialog::OnLButtonUp(nFlags, point);
    }
    void CShotDlg::OnMouseMove(UINT nFlags, CPoint point)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        if(start)
        {
            CDC *pDC=GetDC();
            CPen pen(PS_SOLID,2,RGB(255,0,0));
            CPen *oldp=pDC->SelectObject(&pen);
            int nmode=pDC->SetROP2(R2_NOTXORPEN);
            pDC->Rectangle(opt.x,opt.y,lastmove.x,lastmove.y);
    
            lastmove=point;
    
            pDC->Rectangle(opt.x,opt.y,lastmove.x,lastmove.y);
            nmode=pDC->SetROP2(nmode);
            pDC->SelectObject(oldp);
            ReleaseDC(pDC);        
    
        }
        CDialog::OnMouseMove(nFlags, point);
    }
    void CShotDlg::OnRButtonDown(UINT nFlags, CPoint point)
    {
        // TODO: 在此添加消息处理程序代码和/或调用默认值
        start=false;
        captured=false;
        OnCancel();
        CDialog::OnRButtonDown(nFlags, point);
    }

    都加完后,编译下项目。生成成功。

    10.去UG的代码里面调用这个MFC类里的方法

    先在头文件里定义变量和函数

        int limit;
        bool hasdc;
        CDC picdc;
        CBitmap* pold;
        CBitmap bmp;
        int pw,ph;
        int enlarge;
    
        void save_picture(CString path,CString num);

    在去update_cb里的button0控件那写代码

           label0->SetLabel("开始截图");
                button0->SetEnable(false);
    
                if(hasdc)
                {
                    picdc.SelectObject(pold);
                    bmp.DeleteObject();
                    picdc.DeleteDC();
                }
                pw=ph=0;
    
                AFX_MANAGE_STATE(AfxGetStaticModuleState());
                CShotDlg *g = new CShotDlg();
                g->LIMITE=limit;
                g->DoModal();    
    
                if(g->captured)
                {
                    CPoint lt=g->GetLt();CPoint rb=g->GetRb();
                    lt.Offset(-enlarge,-enlarge);
                    rb.Offset(enlarge,enlarge);
                    int w=rb.x-lt.x;
                    int h=rb.y-lt.y;
                    pw=w;ph=h;
                    CDC* pDC=g->GetBmpDC();
                    picdc.CreateCompatibleDC(pDC);
                    bmp.CreateCompatibleBitmap(pDC,rb.x-lt.x,rb.y-lt.y);
                    pold=picdc.SelectObject(&bmp);
                    picdc.BitBlt(0,0,rb.x-lt.x,rb.y-lt.y,g->GetBmpDC(),lt.x,lt.y,SRCCOPY);
    
                    CString str = "D:\1\2\";//保存路径
                    CString str1 = "1";//保存名字
    
                    hasdc=true;
                    save_picture(str,str1);
                    g->SendMessage(WM_CLOSE);
    
                    label0->SetLabel("结束截图");
                    button0->SetEnable(true);
                }

    去构造函数里加代码

    hasdc=false;pw=ph=0;limit=5;enlarge=0;

    去析构函数里加代码

        if(hasdc)
        {
            picdc.SelectObject(pold);
            bmp.DeleteObject();
            picdc.DeleteDC();
        }

    添加一个函数

    void ScreenShotTool::save_picture(CString path,CString num)
    {
        int nwidth=pw;
        int nheight=ph;
        int bpp=24;
    
        CImage img;
        img.Create(nwidth,nheight,bpp);
        BOOL X=::BitBlt(img.GetDC(),0,0,nwidth,nheight,picdc.m_hDC,0,0,SRCCOPY);
    
        CString strFileName=path; 
        CTime t = CTime::GetCurrentTime(); 
        CString tt = t.Format("%Y%m%d%H%M%S"); 
        strFileName  = strFileName+num+"_"+tt; 
        strFileName += _T(".png"); 
        HRESULT Y=img.Save(strFileName);
        img.ReleaseDC();
        if(X==TRUE && Y>=0)
        {
            uc1601("截取成功", 1);
        }
        else
        {
            uc1601("截取失败", 1);
        }
    
    }

    加上ug的头文件

    #include <uf.h>
    #include <uf_ui.h>

    到这里就全部写完了

    去测试执行一下

    没问题,可以的。

    但是一般我不建议直接在UG项目里这样写,太麻烦的,也没法重用。

    比较好一点的方法是先拿MFC开发一个应用程序,然后每次去调那个exe去传参截图。这样很多场合都可以重用。

    回头我在写一个MFC截图的一个应用程序

    会把文章连接补充在这里的

    Caesar卢尚宇

    2021年3月13日

    作者: 阿飞

    出处: https://www.cnblogs.com/nxopen2018/>

    关于作者:......

    如有问题, 可在底部(留言)咨询.

  • 相关阅读:
    AntDesign(React)学习-9 Dva model reducer实践
    AntDesign(React)学习-8 Menu使用 切换框架页内容页面
    AntDesign(React)学习-7 Menu添加事件
    AntDesign(React)学习-6 Menu展示数据
    AntDesign(React)学习-5 路由及使用Layout布局
    AntDesign(React)学习-4 登录页面提交数据简单实现
    AntDesign(React)学习-3 React基础
    AntDesign(React)学习-2 第一个页面
    AntDesign(React)学习-1 创建环境
    正则表达式分组捕获非捕获的示例理解
  • 原文地址:https://www.cnblogs.com/nxopen2018/p/14529883.html
Copyright © 2020-2023  润新知