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

  • 版本

NX9+VS2012

 

  • 演示

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

 

  • 开发思路

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

 

  • 开发步骤

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

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

 

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

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

 

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

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

 

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

 

 如下

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

 

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

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

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

 

 4.为对话框添加类

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

 

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

 

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

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

 

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

 

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

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

 

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

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

 

 7.更改基类

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

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

 

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

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

 

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

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

 

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

 头文件里定义变量

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

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

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

    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);

加在析构函数里的代码

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

 

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

加在初始化里的代码

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

 

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

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

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

 

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

 

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

 

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

 

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

 步骤如下

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

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

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

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

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类里的方法

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

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

 

 

    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控件那写代码

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

 

       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);
            }

去构造函数里加代码

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

 

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

去析构函数里加代码

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

 

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

添加一个函数

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

 

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的头文件

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

 

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

到这里就全部写完了

去测试执行一下

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

 

没问题,可以的。

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

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

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

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

 

Caesar卢尚宇

2021年3月13日

上一篇:SAP MM- BAPI_PO_CHANGE 更新PO version 信息(version management)


下一篇:(BADI)Copy PR header text to PO header when ME21N