فهرست منبع

蘭雅CPG 异形群组功能增加

蘭雅sRGB 2 ماه پیش
والد
کامیت
99d26d4abd

+ 132 - 0
09_BoundaryGroup/BoundaryGroup.cpp

@@ -0,0 +1,132 @@
+#include "cdrapp.h"
+
+#define GET_BOUNDING_BOX(box)                                                  \
+  GetBoundingBox(&(box).x, &(box).y, &(box).w, &(box).h, false)
+
+#define ZERO_4PC 0, 0, 0, 0
+
+typedef struct {
+  double x; // 左下角 x 坐标
+  double y; // 左下角 y 坐标
+  double w; // 宽度
+  double h; // 高度
+} BoundingBox;
+bool isDPCurve(IVGShapePtr s) {
+  auto dpc = (s->Type == cdrRectangleShape) || (s->Type == cdrEllipseShape) ||
+             (s->Type == cdrCurveShape) || (s->Type == cdrPolygonShape) ||
+             (s->Type == cdrBitmapShape);
+  return dpc;
+}
+IVGShapePtr CreateBoundary(corel *cdr, IVGShapePtr s) {
+  auto scp = s->CreateBoundary(0, 0, true, false);
+
+  //  这个 API X7 以上才支持,所以现在直接画矩形
+  // BoundingBox box;
+  // s->GET_BOUNDING_BOX(box);
+  // auto scp = cdr->ActiveLayer->CreateRectangle2(box.x, box.y, box.w, box.h,
+  // ZERO_4PC);
+
+  return scp;
+}
+
+// VGCore::IVGShapePtr VGCore::IVGShape::CreateBoundary ( double x, double y,
+// VARIANT_BOOL PlaceOnTop, VARIANT_BOOL DeleteSource ); VGCore::IVGShapePtr
+// VGCore::IVGShapeRange::CreateBoundary ( double x, double y, VARIANT_BOOL
+// PlaceOnTop, VARIANT_BOOL DeleteSource ); VARIANT_BOOL
+// VGCore::IVGCurve::IntersectsWith ( struct IVGCurve * Curve )
+bool isIntWith(corel *cdr, IVGShape *s1, IVGShape *s2) {
+  bool isIn = false;
+  if (isDPCurve(s1) && isDPCurve(s2)) {
+    isIn = s1->GetDisplayCurve()->IntersectsWith(s2->GetDisplayCurve());
+  } else if (isDPCurve(s1)) {
+    // 群组文字和OLE等其他类型,创建一个临时边界范围
+    auto scp = CreateBoundary(cdr, s2);
+    isIn = s1->GetDisplayCurve()->IntersectsWith(scp->GetDisplayCurve());
+    scp->Delete();
+
+  } else if (isDPCurve(s2)) {
+    auto scp = CreateBoundary(cdr, s1);
+    isIn = scp->GetDisplayCurve()->IntersectsWith(s2->GetDisplayCurve());
+    scp->Delete();
+  } else {
+    auto scp = CreateBoundary(cdr, s1);
+    auto scp2 = CreateBoundary(cdr, s2);
+    isIn = scp->GetDisplayCurve()->IntersectsWith(scp2->GetDisplayCurve());
+    scp->Delete();
+    scp2->Delete();
+  }
+  return isIn;
+}
+
+// 从矩形边界坐标 获得中心坐标
+void calculate_center(const BoundingBox *box, double *cx, double *cy) {
+  *cx = box->x + (box->w / 2);
+  *cy = box->y + (box->h / 2);
+}
+
+// VGCore::cdrPositionOfPointOverShape VGCore::IVGShape::IsOnShape ( double x,
+// double y, double HotArea ); VGCore::cdrPositionOfPointOverShape
+// VGCore::IVGCurve::IsOnCurve ( double x, double y, double HotArea );
+
+bool BoundaryGroup(corel *cdr, IVGShapeRange *sr, IVGShapeRange *srs) {
+
+  if (sr->Count < 2)
+    return false;
+
+  BoundingBox box;
+  double x, y;
+  int OnSh = 0;
+  auto bounds = sr->CreateBoundary(0, 0, true, false); // 建立异性边界物件
+  bounds->Fill->UniformColor->RGBAssign(255, 0, 0);    // 填充红色
+
+  auto sbox = bounds->BreakApartEx(); // 把边界 拆分为多个边界 用来分组
+
+  auto srgp = cdr->CreateShapeRange();
+
+  for (int k = 0; k < sbox->Count; k++) {
+
+    for (int i = 0; i < sr->Count; i++) {
+      auto sh = sr->Shapes->Item[i + 1];
+      sh->GET_BOUNDING_BOX(box);      // 获得物件矩形边界坐标
+      calculate_center(&box, &x, &y); // 获得物件中心坐标
+      OnSh = sbox->Shapes->Item[k + 1]->IsOnShape(x, y, -1);
+
+      if (OnSh) {
+        srgp->Add(sh);
+      } else if (isIntWith(cdr, sbox->Shapes->Item[k + 1], sh)) {
+        srgp->Add(sh);
+      }
+    }
+    // 从Range中移除已分组的图形
+    sr->RemoveRange(srgp);
+    srs->Add(srgp->Group());
+    srgp->RemoveAll();
+  }
+  sbox->Delete();
+  
+  return true;
+}
+
+// 测试运行 异形群组
+void run_BoundaryGroup(corel *cdr) {
+  auto start = std::chrono::high_resolution_clock::now(); // 开始时间
+  BeginOpt(cdr);
+
+  auto sr = cdr->ActiveSelectionRange;
+  auto srs = cdr->CreateShapeRange();
+  int cnt = sr->Count;
+
+  cdr->ActiveDocument->ClearSelection();
+  BoundaryGroup(cdr, sr, srs);
+  srs->CreateSelection();
+
+  // 计算持续时间
+  double runtime = 0.0;
+  auto end = std::chrono::high_resolution_clock::now();
+  std::chrono::duration<double> duration = end - start;
+  runtime = duration.count();
+
+  sprintf(infobuf, "选择物件: %d 个进行异形群组\n群组: %d 组, 时间: %.2f秒",
+          cnt, srs->Count, runtime);
+  EndOpt(cdr);
+}

BIN
09_BoundaryGroup/LYVBA.ico


BIN
09_BoundaryGroup/Makefile


+ 291 - 0
09_BoundaryGroup/ToolsBox.cpp

@@ -0,0 +1,291 @@
+#include "cdrapp.h"
+#include <stdio.h>
+#include <windows.h>
+#include "resource.h"
+
+corel *cdr = NULL;
+static HINSTANCE g_hResource = NULL;
+char infobuf[256] = {0};
+BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    if (fdwReason == DLL_PROCESS_ATTACH) {
+        g_hResource = (HINSTANCE)hinstDLL;
+    }
+    return TRUE;
+}
+
+class ToolsBoxPlugin : public VGCore::IVGAppPlugin
+{
+private:
+
+    volatile ULONG m_ulRefCount;
+    long m_lCookie;
+
+    static intptr_t CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+    void OpenToolsBox();
+
+
+public:
+    ToolsBoxPlugin();
+    VGCore::IVGApplication* m_pApp;
+
+// IUnknown
+public:
+    STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject);
+    STDMETHOD_(ULONG, AddRef)(void) { return ++m_ulRefCount; }
+    STDMETHOD_(ULONG, Release)(void)
+    {
+        ULONG ulCount = --m_ulRefCount;
+        if (ulCount == 0) {
+            delete this;
+        }
+        return ulCount;
+    }
+
+// IDispatch
+public:
+    STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) { return E_NOTIMPL; }
+    STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) { return E_NOTIMPL; }
+    STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) { return E_NOTIMPL; }
+    STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr);
+
+// IVGAppPlugin
+public:
+    STDMETHOD(raw_OnLoad)(VGCore::IVGApplication* Application);
+    STDMETHOD(raw_StartSession)();
+    STDMETHOD(raw_StopSession)();
+    STDMETHOD(raw_OnUnload)();
+
+};
+
+ToolsBoxPlugin::ToolsBoxPlugin()
+{
+    m_pApp = NULL;
+    m_lCookie = 0;
+    m_ulRefCount = 1;
+}
+
+STDMETHODIMP ToolsBoxPlugin::QueryInterface(REFIID riid, void** ppvObject)
+{
+    HRESULT hr = S_OK;
+    m_ulRefCount++;
+    if (riid == IID_IUnknown) {
+        *ppvObject = (IUnknown*)this;
+    } else if (riid == IID_IDispatch) {
+        *ppvObject = (IDispatch*)this;
+    } else if (riid == __uuidof(VGCore::IVGAppPlugin)) {
+        *ppvObject = (VGCore::IVGAppPlugin*)this;
+    } else {
+        m_ulRefCount--;
+        hr = E_NOINTERFACE;
+    }
+    return hr;
+}
+
+STDMETHODIMP ToolsBoxPlugin::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+    switch (dispIdMember) {
+
+    case 0x0014: // DISPID_APP_ONPLUGINCMD
+        if (pDispParams != NULL && pDispParams->cArgs == 1) {
+            _bstr_t strCmd(pDispParams->rgvarg[0].bstrVal);
+            if (strCmd == _bstr_t("OpenToolsBox")) {
+                //   MessageBox(NULL, _bstr_t("OpenToolsBox"), _bstr_t("OpenToolsBox"), MB_ICONSTOP);
+                OpenToolsBox();
+            }
+        }
+        break;
+
+    case 0x0015: // DISPID_APP_ONPLUGINCMDSTATE
+        if (pDispParams != NULL && pDispParams->cArgs == 3) {
+            _bstr_t strCmd(pDispParams->rgvarg[2].bstrVal);
+            if (strCmd == _bstr_t("OpenToolsBox")) {
+                *pDispParams->rgvarg[1].pboolVal = VARIANT_TRUE;
+            }
+        }
+        break;
+    }
+    return S_OK;
+}
+
+STDMETHODIMP ToolsBoxPlugin::raw_OnLoad(VGCore::IVGApplication* Application)
+{
+    m_pApp = Application;
+    if (m_pApp) {
+        m_pApp->AddRef();
+    }
+    return S_OK;
+}
+
+STDMETHODIMP ToolsBoxPlugin::raw_StartSession()
+{
+    // 接口转交给cdr
+    cdr = m_pApp;
+
+    try {
+        m_pApp->AddPluginCommand(_bstr_t("OpenToolsBox"), _bstr_t("Tools Box"), _bstr_t("打开工具窗口"));
+
+        VGCore::ICUIControlPtr ctl = m_pApp->CommandBars->Item[_bstr_t("Standard")]->Controls->AddCustomButton(VGCore::cdrCmdCategoryPlugins, _bstr_t("OpenToolsBox"), 10, VARIANT_FALSE);
+        ctl->SetIcon2(_bstr_t("guid://d2fdc0d9-09f8-4948-944c-4297395c05b7"));
+        m_lCookie = m_pApp->AdviseEvents(this);
+    } catch (_com_error &e) {
+        MessageBox(NULL, e.Description(), _bstr_t("Error"), MB_ICONSTOP);
+    }
+    return S_OK;
+}
+
+STDMETHODIMP ToolsBoxPlugin::raw_StopSession()
+{
+    try {
+        m_pApp->UnadviseEvents(m_lCookie);
+        m_pApp->RemovePluginCommand(_bstr_t("OpenToolsBox"));
+    } catch (_com_error &e) {
+        MessageBox(NULL, e.Description(), _bstr_t("Error"), MB_ICONSTOP);
+    }
+    return S_OK;
+}
+
+STDMETHODIMP ToolsBoxPlugin::raw_OnUnload()
+{
+    if (m_pApp) {
+        m_pApp->Release();
+        m_pApp = NULL;
+    }
+    return S_OK;
+}
+
+void ToolsBoxPlugin::OpenToolsBox()
+{
+    m_pApp->StartupMode = VGCore::cdrStartupDoNothing;
+
+    intptr_t nHandle = m_pApp->AppWindow->Handle;
+    HWND hAppWnd = reinterpret_cast<HWND>(nHandle);
+
+    // 创建非模态对话框
+    HWND hDlgWnd = CreateDialogParam(g_hResource, MAKEINTRESOURCE(IDD_TOOLS_BOX), hAppWnd, DlgProc, (LPARAM)m_pApp);
+    // 在创建对话框之前存储 m_pApp 指针
+    SetWindowLongPtr(hDlgWnd, DWLP_USER, (LONG_PTR)m_pApp);
+
+    // 获取屏幕的宽度和高度
+    RECT rect;
+    GetWindowRect(GetDesktopWindow(), &rect);
+    int screenWidth = rect.right - rect.left;
+    int screenHeight = rect.bottom - rect.top;
+
+    // 计算对话框窗口的宽度和高度
+    RECT dlgRect;
+    GetWindowRect(hDlgWnd, &dlgRect);
+    int dlgWidth = dlgRect.right - dlgRect.left;
+    int dlgHeight = dlgRect.bottom - dlgRect.top;
+
+    // 计算对话框窗口的左上角坐标,使其居中显示
+    int x = (screenWidth - dlgWidth) / 2;
+    int y = (screenHeight - dlgHeight) / 2;
+
+    // 设置对话框窗口的位置
+    SetWindowPos(hDlgWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+    // 设置对话框窗口的父窗口  // #define GWL_HWNDPARENT      (-8)
+    SetWindowLong(hDlgWnd, -8, (LONG)hAppWnd);
+    // 显示对话框窗口
+    ShowWindow(hDlgWnd, SW_SHOW);
+}
+
+
+// MessageBox(NULL, "更新提示信息: 激活CorelDRAW窗口", "CPG代码测试", MB_ICONSTOP);
+#define UPDATE_INFO_ACTIVE_CDRWND  \
+    PutTextValue(hDlg, INFO_TEXT, infobuf); Active_CorelWindows(hDlg);
+intptr_t CALLBACK ToolsBoxPlugin::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    // 从附加数据中获取 m_pApp 指针
+    VGCore::IVGApplication* cdr = reinterpret_cast<VGCore::IVGApplication*>(GetWindowLongPtr(hDlg, DWLP_USER));
+
+    if (uMsg == WM_COMMAND) {
+        try {
+            switch (LOWORD(wParam)) {
+
+            case ID_BOUNDARY_GROUP :{
+                    double exp = GetTextValue(hDlg, EXP_TEXT);
+                    AutoMakeSelection(cdr);
+                    run_BoundaryGroup(cdr);
+                    UPDATE_INFO_ACTIVE_CDRWND    
+                }
+                break;
+
+
+            case IDC_BOX_GROUP :{
+                    double exp = GetTextValue(hDlg, EXP_TEXT);
+                    AutoMakeSelection(cdr);
+                    Box_AutoGroup(cdr, exp);
+                    UPDATE_INFO_ACTIVE_CDRWND
+
+                }
+                break;
+
+            case IDC_CQL_OUTLINE:
+                cql_OutlineColor(cdr);
+
+                UPDATE_INFO_ACTIVE_CDRWND
+                break;
+
+            case IDC_CQL_FILL:
+                cql_FillColor(cdr);
+
+                UPDATE_INFO_ACTIVE_CDRWND
+                break;
+
+            case IDC_CQL_SIZE:
+                cql_SameSize(cdr);
+
+                UPDATE_INFO_ACTIVE_CDRWND
+                break;
+
+            case IDC_CLEAR_FILL:{
+                    double exp = GetTextValue(hDlg, EXP_TEXT);
+                    AutoMakeSelection(cdr);
+                    BBox_DrawRectangle(cdr, exp);
+                    
+                    UPDATE_INFO_ACTIVE_CDRWND
+                }
+                break;
+
+            case IDC_SR_FLIP:
+                Shapes_Filp(cdr);
+                break;
+
+            case IDC_CDR2AI:{    
+                CdrCopy_to_AdobeAI(cdr);
+                sprintf(infobuf, "把CorelDRAW软件中选择物件复制到剪贴板,请切换到AI软件粘贴");
+                UPDATE_INFO_ACTIVE_CDRWND
+                }
+
+                break;
+
+            case IDC_AI2CDR:{
+                AdobeAI_Copy_ImportCdr(cdr);
+                sprintf(infobuf, "请先在AI软件选择物件复制,再切换到CorelDRAW软件点执行本功能");
+                UPDATE_INFO_ACTIVE_CDRWND
+                }
+                break;
+
+            case IDOK:
+            case IDCANCEL:
+                EndDialog(hDlg, 0);
+                break;
+            }
+
+        } catch (_com_error &e) {
+            MessageBox(NULL, e.Description(), "Error", MB_ICONSTOP);
+        }
+
+    } else if (uMsg == WM_INITDIALOG) {
+             SetWindowText(::GetDlgItem(hDlg, EXP_TEXT), "0");
+        return 1;
+    }
+    return 0;
+}
+
+extern "C" __declspec(dllexport) DWORD APIENTRY AttachPlugin(VGCore::IVGAppPlugin** ppIPlugin)
+{
+    *ppIPlugin = new ToolsBoxPlugin;
+    return 0x100;
+}

+ 42 - 0
09_BoundaryGroup/ToolsBox.rc

@@ -0,0 +1,42 @@
+// Generated by ResEdit 1.6.6
+// Copyright (C) 2006-2015
+// http://www.resedit.net
+
+#include <windows.h>
+#include <commctrl.h>
+#include <richedit.h>
+#include "resource.h"
+
+
+
+
+//
+// Dialog resources
+//
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+IDD_TOOLS_BOX DIALOGEX 0, 0, 142, 129
+STYLE DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU
+CAPTION "蘭雅 CPG 插件 福利群版"
+FONT 8, "MS Shell Dlg", 400, 0, 1
+{
+    CTEXT           "蘭雅 CorelDRAW CPG 插件\n2024.8.8 智能群组版", INFO_TEXT, 6, 105, 126, 17, SS_CENTER, WS_EX_LEFT
+    PUSHBUTTON      "方框智能群组", IDC_BOX_GROUP, 73, 2, 59, 21, 0, WS_EX_LEFT
+    PUSHBUTTON      "CQL轮廓色相同", IDC_CQL_OUTLINE, 9, 40, 59, 18, 0, WS_EX_LEFT
+    PUSHBUTTON      "边界画矩形", IDC_CLEAR_FILL, 74, 36, 59, 19, 0, WS_EX_LEFT
+    PUSHBUTTON      "批量镜像", IDC_SR_FLIP, 73, 57, 59, 19, 0, WS_EX_LEFT
+    PUSHBUTTON      "CQL颜色相同", IDC_CQL_FILL, 9, 57, 59, 22, 0, WS_EX_LEFT
+    PUSHBUTTON      "CQL尺寸相同", IDC_CQL_SIZE, 9, 22, 59, 18, 0, WS_EX_LEFT
+    PUSHBUTTON      "CDR复制到AI", IDC_CDR2AI, 9, 78, 59, 24, 0, WS_EX_LEFT
+    PUSHBUTTON      "AI粘贴到CDR", IDC_AI2CDR, 74, 78, 59, 24, 0, WS_EX_LEFT
+    LTEXT           "容差:(mm)", EXP_LT, 72, 25, 37, 9, SS_LEFT, WS_EX_LEFT
+    EDITTEXT        EXP_TEXT, 107, 23, 28, 14, NOT WS_TABSTOP | ES_AUTOHSCROLL, WS_EX_DLGMODALFRAME
+    PUSHBUTTON      "异形群组", ID_BOUNDARY_GROUP, 9, 2, 59, 19, 0, WS_EX_LEFT
+}
+
+
+
+//
+// Icon resources
+//
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+IDI_ICON1          ICON           ".\\LYVBA.ico"

+ 50 - 0
09_BoundaryGroup/VBA_GMS/VbaCallCPG.bas

@@ -0,0 +1,50 @@
+Attribute VB_Name = "VbaCallCPG"
+Private Declare PtrSafe Function vbadll Lib "lycpg64.cpg" (ByVal code As Long, ByVal x As Double) As Long
+
+Sub VBA调用CPG_CDR复制物件到AI()
+ ret = vbadll(2, 0)
+ MsgBox "CDR复制物件到AI 功能 " & ret
+End Sub
+
+Sub AI复制物件到CDR()
+ ret = vbadll(1, 0)
+ MsgBox "AI复制物件到CDR 功能 " & ret
+End Sub
+
+Sub Clear_Fill()
+ ret = vbadll(3, 0)
+ MsgBox "Clear_Fill功能 " & ret
+End Sub
+
+
+Sub cql_FillColor()
+ ret = vbadll(5, 0)
+End Sub
+
+
+Sub Shapes_Filp()
+ ret = vbadll(4, 0)
+End Sub
+
+Sub cql_OutlineColor()
+ ret = vbadll(6, 0)
+End Sub
+
+Sub cql_SameSize()
+ ret = vbadll(7, 0)
+End Sub
+
+Sub fill_red()
+ ret = vbadll(8, 0)
+End Sub
+
+'// 第9号功能: 按边界批量绘制矩形  参数:正数向外,负数向内
+Sub BBox_DrawRectangle()
+ ret = vbadll(9, -2#)
+End Sub
+
+'// 第10号功能: 智能群组功能  参数:正数 向外容差  负数 向内容差
+Sub Box_AutoGroup()
+ ret = vbadll(10, -2#)
+End Sub
+

+ 6 - 0
09_BoundaryGroup/VBA_GMS/使用视频.txt

@@ -0,0 +1,6 @@
+【蘭雅 CorelDRAW CPG 插件:  VBA 调用 C++ cpg 插件,达到加密和简单做界面的效果】 
+
+https://www.bilibili.com/video/BV1cZ421T7u7
+
+VBA GMS 调用 CPG源码:
+VbaCallCPG.bas  

+ 205 - 0
09_BoundaryGroup/boxAutoGroup.cpp

@@ -0,0 +1,205 @@
+#include "cdrapp.h"
+
+#define GET_BOUNDING_BOX(box)                                                  \
+  GetBoundingBox(&(box).x, &(box).y, &(box).w, &(box).h, false)
+
+#define ZERO_4PC 0, 0, 0, 0
+
+typedef struct {
+  double x; // 左下角 x 坐标
+  double y; // 左下角 y 坐标
+  double w; // 宽度
+  double h; // 高度
+} BoundingBox;
+
+// 扩展边界框
+void expand_bounding_boxes(std::vector<BoundingBox>& boxes, double exp) {
+    for (auto& box : boxes) {
+        // 扩展宽度和高度
+        box.w += 2 * exp; // 左右各扩展
+        box.h += 2 * exp; // 上下各扩展
+        // 调整左下角坐标
+        box.x -= exp; // 向左扩展
+        box.y -= exp; // 向下扩展
+    }
+}
+
+double get_bounding_box_area(BoundingBox box) { return box.w * box.h; }
+
+// 自定义比较函数,按 BoundingBox 的面积大小进行排序
+bool compare_bounding_boxes(const std::pair<int, BoundingBox> &a,
+                            const std::pair<int, BoundingBox> &b) {
+  return get_bounding_box_area(a.second) > get_bounding_box_area(b.second);
+}
+
+// 查找父节点
+int find(std::vector<int>& parent, int x) {
+    if (parent[x] != x) {
+        parent[x] = find(parent, parent[x]);
+    }
+    return parent[x];
+}
+
+// 合并两个集合
+void unionSet(std::vector<int>& parent, int x, int y) {
+    int xroot = find(parent, x);
+    int yroot = find(parent, y);
+    parent[xroot] = yroot;
+}
+// 检查两个矩形是否重叠
+bool isOverlapped(const BoundingBox &a, const BoundingBox &b) {
+  return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;
+} // 函数使用AABB(Axis-Aligned Bounding Box)碰撞检测
+
+bool BBox_DrawRectangle(corel *cdr, double exp) {
+  BoundingBox box;
+  auto sr = cdr->ActiveSelectionRange; // 获得选择范围
+  auto al = cdr->ActiveLayer;          // 获得当前层
+  if (!sr || !al) return false;
+  
+  BeginOpt(cdr);
+  auto srs = cdr->CreateShapeRange();
+
+  // CorelDRAW Shapes 物件 Item 编号从1开始
+  for (auto i = 0; i != sr->Count; i++) {
+    sr->Shapes->Item[i + 1]->GET_BOUNDING_BOX(box); // 获得Shapes的BoundingBox,赋值到box
+    if (fabs(exp) > 0.02 ) { box.w += 2 * exp; box.h += 2 * exp; box.x -= exp; box.y -= exp; }
+    
+    auto s = al->CreateRectangle2(box.x, box.y, box.w, box.h, ZERO_4PC); // 使用BoundingBox box 创建一个矩形
+    s->Outline->Color->RGBAssign(0, 255, 0);
+    srs->Add(s);
+  }
+  srs->CreateSelection();
+  
+  sprintf(infobuf, "提示: 标记画框数量: %d 个\n容差值请使用小键盘输入", srs->Count);
+  EndOpt(cdr);
+  return true;
+}
+
+bool AutoMakeSelection(corel *cdr) {
+  auto sr = cdr->ActiveSelectionRange; 
+  if (0 == sr->Count) {
+    auto all = cdr->ActiveDocument->ActivePage->Shapes->All();
+    all->CreateSelection();
+  }
+  return true;
+}
+
+// 快速分组重叠的区域, 使用算法"Union-Find" 算法。这个算法可以有效地处理这种并集问题。
+// 算法的时间复杂度为 O(n^2),其中 n 是矩形的数量。如果矩形数量较多,可以考虑使用更高效的算法,
+// 例如使用四叉树(Quadtree)或者区间树(Interval Tree)等数据结构来加速计算。
+bool Box_AutoGroup(corel *cdr, double exp) {
+  BoundingBox box;
+
+  auto sr = cdr->ActiveSelectionRange; // 获得选择范围
+  auto al = cdr->ActiveLayer;          // 获得当前层
+  if (!sr || !al) return false;
+
+  auto start = std::chrono::high_resolution_clock::now(); // 开始时间
+  BeginOpt(cdr);
+
+  std::vector<BoundingBox> boxes;
+  std::vector<int> parent;
+
+  // CorelDRAW Shapes 物件 Item 编号从1开始
+  for (auto i = 0; i != sr->Count; i++) {
+    sr->Shapes->Item[i + 1]->GET_BOUNDING_BOX(box);
+    boxes.push_back(box);
+    parent.push_back(i);
+  }
+
+  // 扩展边界框,或者收缩边界框
+  if (fabs(exp) > 0.02 ) {
+    expand_bounding_boxes(boxes, exp);
+  }
+
+  // 实现 Union-Find 算法来合并重叠的区域
+  for (int i = 0; i < boxes.size(); i++) {
+    for (int j = i + 1; j < boxes.size(); j++) {
+      if (isOverlapped(boxes[i], boxes[j])) {
+        unionSet(parent, i, j);
+      }
+    }
+  }
+
+  double runtime[2] = {0,0};
+  auto end = std::chrono::high_resolution_clock::now(); 
+  std::chrono::duration<double> duration = end - start;
+  runtime[0] = duration.count();
+
+ // 输出分组结果到文件
+  // std::ofstream output_file("D:\\group.txt");
+  // if (output_file.is_open()) {
+  //     std::map<int, std::vector<int>> groups;
+  //     for (int i = 0; i < parent.size(); i++) {
+  //         int root = find(parent, i);
+  //         groups[root].push_back(i + 1); // CorelDRAW Shapes 物件 Item 编号从1开始
+  //     }
+
+  //     for (const auto& group : groups) {
+  //         output_file << "Group: ";
+  //         for (int index : group.second) {
+  //             output_file << index << " ";
+  //         }
+  //         output_file << std::endl;
+  //     }
+
+  //   auto end = std::chrono::high_resolution_clock::now(); // 结束时间
+  //   // 计算持续时间
+  //   std::chrono::duration<double> duration = end - start;
+  //   output_file << "Execution time: " << duration.count() << " seconds\n";
+
+  //   output_file.close();
+  // } 
+
+  // 输出分组结果
+  std::map<int, std::vector<int>> groups;
+  for (int i = 0; i < parent.size(); i++) {
+    int root = find(parent, i);
+    groups[root].push_back(i + 1); // CorelDRAW Shapes 物件 Item 编号从1开始
+  }
+
+  auto srgp = cdr->CreateShapeRange();
+  auto srs = cdr->CreateShapeRange();
+
+  cdr->ActiveDocument->ClearSelection();
+// 原来 没有取消选择 最初速度
+// Execution time: 63.0305 seconds
+
+// srgp->GET_BOUNDING_BOX(box); 
+// al->CreateRectangle2(box.x, box.y, box.w, box.h, ZERO_4PC); // 使用边界 创建一个矩形
+// box边界 转左上和右下坐标 box.x, box.y + box.h, box.x + box.w, box.y
+// auto sh = cdr->ActivePage->SelectShapesFromRectangle(box.x, box.y + box.h, box.x + box.w, box.y, false);
+// sh->Group();
+// 使用 SelectShapesFromRectangle 框选的形状进行群组
+// Execution time: 2.44753 seconds
+
+// cdr->ActiveDocument->ClearSelection(); // 使用取消选择
+// Execution time: 1.7432 seconds
+
+// srgp->CreateSelection();
+// cdr->ActiveSelectionRange->Group();
+// Execution time: 1.87662 seconds
+
+  // 分组分别进行群组
+  for (const auto& group : groups) {
+      for (int index : group.second) 
+        srgp->Add(sr->Shapes->Item[index]);
+      
+      if(sr->Count >1)
+        srs->Add(srgp->Group());
+      else
+        srs->AddRange(srgp);  
+
+      srgp->RemoveAll();
+  }
+  srs->CreateSelection();
+
+  // 计算持续时间
+  duration = std::chrono::high_resolution_clock::now() - start;
+  runtime[1] = duration.count();
+
+  sprintf(infobuf, "选择物件: %d 个, 分组: %.2f秒\n总共群组: %d 组, 总时间: %.2f秒", sr->Count, runtime[0] + 0.01, srs->Count, runtime[1] + 0.02);
+  EndOpt(cdr);
+  return true;
+}

+ 180 - 0
09_BoundaryGroup/cdrPDF2Clip.cpp

@@ -0,0 +1,180 @@
+#include "cdrapp.h"
+#include <stdio.h>
+#include <windows.h>
+#include <thread>
+#include <chrono>
+
+
+
+#define CUSTOM_FORMAT RegisterClipboardFormatA("Portable Document Format")
+
+bool pdf_to_clipboard(const char *pdffile)
+{
+    // 打开剪贴板
+    if (!OpenClipboard(NULL)) {
+        printf("Failed to open clipboard.\n");
+        return false;
+    }
+
+    // 清空剪贴板
+    EmptyClipboard();
+
+    // 读取PDF文件到内存
+    FILE *file = fopen(pdffile, "rb");
+    if (!file) {
+        printf("Failed to open file.\n");
+        CloseClipboard();
+        return false;
+    }
+
+    // 获取文件大小
+    fseek(file, 0, SEEK_END);
+    size_t fileSize = ftell(file);
+    fseek(file, 0, SEEK_SET);
+
+    // 分配内存并读取文件内容
+    void *pdfData = malloc(fileSize);
+    if (!pdfData) {
+        printf("Failed to allocate memory.\n");
+        fclose(file);
+        CloseClipboard();
+        return false;
+    }
+
+    fread(pdfData, 1, fileSize, file);
+    fclose(file);
+
+    // 将二进制数据写入剪贴板
+    HGLOBAL hGlobal = GlobalAlloc(GHND, fileSize);
+    if (!hGlobal) {
+        printf("Failed to allocate global memory.\n");
+        free(pdfData);
+        CloseClipboard();
+        return false;
+    }
+
+    memcpy(GlobalLock(hGlobal), pdfData, fileSize);
+    GlobalUnlock(hGlobal);
+
+    if (!SetClipboardData(CUSTOM_FORMAT, hGlobal)) {
+        printf("Failed to set clipboard data.\n");
+        GlobalFree(hGlobal);
+        free(pdfData);
+        CloseClipboard();
+        return false;
+    }
+    // 关闭剪贴板
+    CloseClipboard();
+
+    printf("PDF binary data copied to clipboard using custom format.\n");
+    // 不要忘记释放内存
+    free(pdfData);
+    return true;
+}
+
+bool clipboard_to_pdf(const char *outputFile)
+{
+    // 打开剪贴板
+    if (!OpenClipboard(NULL)) {
+        printf("Failed to open clipboard.\n");
+        return false;
+    }
+
+    // 获取剪贴板中的PDF数据
+    HANDLE hData = GetClipboardData(CUSTOM_FORMAT);
+    if (!hData) {
+        printf("Failed to get clipboard data.\n");
+        CloseClipboard();
+        return false;
+    }
+
+    // 锁定内存并获取指针
+    void *pdfData = GlobalLock(hData);
+    if (!pdfData) {
+        printf("Failed to lock global memory.\n");
+        CloseClipboard();
+        return false;
+    }
+
+    // 获取PDF数据的大小
+    size_t fileSize = GlobalSize(hData);
+
+    // 将PDF数据写入文件
+    FILE *file = fopen(outputFile, "wb");
+    if (!file) {
+        printf("Failed to open output file.\n");
+        GlobalUnlock(hData);
+        CloseClipboard();
+        return false;
+    }
+
+    fwrite(pdfData, 1, fileSize, file);
+    fclose(file);
+
+    // 解锁内存并关闭剪贴板
+    GlobalUnlock(hData);
+    CloseClipboard();
+
+    printf("PDF binary data from clipboard saved to file: %s\n", outputFile);
+
+    return true;
+}
+
+bool cdr_savepdf(corel *cdr, const char *outputFile)
+{
+    DeleteFile(_bstr_t(outputFile));
+    auto pdfst = cdr->ActiveDocument->PDFSettings;
+    pdfst->BitmapCompression = pdfLZW;
+    pdfst->ColorMode = pdfCMYK;
+    pdfst->EmbedBaseFonts = cdrFalse;
+    pdfst->EmbedFonts = cdrFalse;
+    pdfst->FileInformation = cdrFalse;
+    pdfst->Hyperlinks = cdrFalse;
+    pdfst->IncludeBleed = cdrFalse;
+    pdfst->Linearize = cdrTrue;
+    pdfst->MaintainOPILinks = cdrTrue;
+    pdfst->Overprints = cdrTrue;
+    pdfst->PutpdfVersion(pdfVersion14); //'pdfVersion14 : pdfVersion13;
+    pdfst->PublishRange = pdfSelection;
+    pdfst->RegistrationMarks = cdrFalse;
+    pdfst->SpotColors = cdrTrue;
+    pdfst->Startup = pdfPageOnly;
+    pdfst->SubsetFonts = cdrFalse;
+    pdfst->TextAsCurves = cdrFalse;
+    pdfst->Thumbnails = cdrFalse;
+    cdr->ActiveDocument->PublishToPDF(_bstr_t(outputFile));
+
+    return true;
+}
+
+void CdrCopy_to_AdobeAI(corel *cdr)
+{
+    char path[MAX_PATH] = {0};
+    GetTempPath(MAX_PATH, path);
+    char *f = strcat(path, "CDR2AI.pdf");
+    if (cdr_savepdf(cdr, f))
+        pdf_to_clipboard(f);
+}
+
+bool pdf_ImportCdr(corel *cdr, const char *pdffile)
+{
+   auto si = cdr->CreateStructImportOptions();
+   si->MaintainLayers = true;
+   
+   auto impflt = cdr->ActiveLayer->ImportEx(_bstr_t(pdffile), cdrAutoSense , si);
+   impflt->Finish();
+   return true;
+}
+
+void AdobeAI_Copy_ImportCdr(corel *cdr)
+{
+    char path[MAX_PATH] = {0};
+    GetTempPath(MAX_PATH, path);
+    char *f = strcat(path, "CDR2AI.pdf");
+    if (clipboard_to_pdf(f)){
+        // 延时 0.5 秒
+        std::this_thread::sleep_for(std::chrono::milliseconds(500));
+        pdf_ImportCdr(cdr, f);
+    }
+
+}

+ 41 - 0
09_BoundaryGroup/cdrapi.cpp

@@ -0,0 +1,41 @@
+#include <windows.h>
+#include <stdio.h>
+#include "cdrapi.h"
+
+void BeginOpt(corel *cdr)
+{
+  auto name = _bstr_t("Undo");
+  cdr->EventsEnabled = false;
+  cdr->ActiveDocument->BeginCommandGroup(name);
+  cdr->ActiveDocument->Unit = cdrMillimeter;
+  cdr->Optimization = true;
+}
+
+void EndOpt(corel *cdr)
+{
+  cdr->EventsEnabled = true;
+  cdr->Optimization = false;
+  cdr->EventsEnabled = true;
+  cdr->ActiveDocument->ReferencePoint = cdrBottomLeft;
+  cdr->Application->Refresh();
+  cdr->ActiveDocument->EndCommandGroup();
+}
+
+void Active_CorelWindows(HWND hDlg)
+{                
+  // 将焦点返回到父窗口 关闭对话框窗口
+  SetFocus(GetParent(hDlg));
+}
+
+double GetTextValue(HWND hDlg, int IDITEM) {
+    char ibuf[64];
+    memset(ibuf, 0, sizeof(ibuf));
+    GetWindowText(::GetDlgItem(hDlg, IDITEM), ibuf, sizeof(ibuf));
+    double exp = 0.0;
+    sscanf_s(ibuf, "%lf", &exp);
+    return exp;
+}
+
+void PutTextValue(HWND hDlg, int IDITEM, char *buf) {
+  SetWindowText(::GetDlgItem(hDlg, IDITEM), buf);
+}

+ 32 - 0
09_BoundaryGroup/cdrapi.h

@@ -0,0 +1,32 @@
+#ifndef CDRAPI_H_INCLUDED
+#define CDRAPI_H_INCLUDED
+
+#define _CRT_SECURE_NO_WARNINGS
+#include <string.h>
+#include <algorithm>
+#include <cstdio>
+#include <map>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <chrono>
+#include <math.h>
+
+#import "VGCoreAuto.tlb" \
+rename("GetCommandLine", "VGGetCommandLine") \
+rename("CopyFile", "VGCore") \
+rename("FindWindow", "VGFindWindow")
+
+#define corel VGCore::IVGApplication
+using namespace VGCore;
+
+
+
+void BeginOpt(corel *cdr);
+void EndOpt(corel *cdr);
+void Active_CorelWindows(HWND hDlg);
+double GetTextValue(HWND hDlg, int IDITEM);
+void PutTextValue(HWND hDlg, int IDITEM, char *buf);
+
+
+#endif // CDRAPI_H_INCLUDED

+ 90 - 0
09_BoundaryGroup/cdrapp.cpp

@@ -0,0 +1,90 @@
+#include "cdrapp.h"
+
+// sr.ApplyUniformFill CreateCMYKColor(0, 100, 100, 0)
+bool fill_red(corel *cdr)
+{
+    auto sr = cdr->ActiveSelectionRange;
+    auto red = cdr->CreateCMYKColor(0, 100, 100, 0);
+    sr->ApplyUniformFill(red);
+
+    return true;
+}
+
+bool cql_OutlineColor(corel *cdr)
+{
+    auto col = cdr->CreateCMYKColor(0, 100, 100, 0);
+    auto s = cdr->ActiveShape;
+    col-> CopyAssign(s->Outline->Color);
+    col->ConvertToRGB();
+
+    auto r = col->RGBRed;
+    auto g = col->RGBGreen;
+    auto b = col->RGBBlue;
+
+    char buf[256] = { 0 };
+    sprintf(buf, "@Outline.Color.rgb[.r='%d' And .g='%d' And .b='%d']", r, g, b);
+    auto cql = _bstr_t(buf);
+    // MessageBox(NULL, cql, "cql 轮廓颜色", MB_ICONSTOP);
+    auto sr = cdr->ActivePage->Shapes->FindShapes(_bstr_t(), cdrNoShape, VARIANT_TRUE, cql);
+    sr->CreateSelection();
+
+    strcpy(infobuf , buf);
+    return true;
+}
+
+bool cql_FillColor(corel *cdr)
+{
+    auto col = cdr->CreateCMYKColor(0, 100, 100, 0);
+    auto s = cdr->ActiveShape;
+    col-> CopyAssign(s->Fill->UniformColor);
+    col->ConvertToRGB();
+
+    auto r = col->RGBRed;
+    auto g = col->RGBGreen;
+    auto b = col->RGBBlue;
+
+    char buf[256] = { 0 };
+    sprintf(buf, "@Fill.Color.rgb[.r='%d' And .g='%d' And .b='%d']", r, g, b);
+    auto cql = _bstr_t(buf);
+
+    auto sr = cdr->ActivePage->Shapes->FindShapes(_bstr_t(), cdrNoShape, VARIANT_TRUE, cql);
+    sr->CreateSelection();
+
+    strcpy(infobuf , buf);
+    return true;
+}
+
+bool cql_SameSize(corel *cdr)
+{
+    cdr->ActiveDocument->Unit = cdrMillimeter;
+    auto s = cdr->ActiveShape;
+
+    char buf[256] = { 0 };
+    sprintf(buf, "@width = {%lf mm} and @height = {%lf mm}", s->SizeWidth, s->SizeHeight);
+    auto cql = _bstr_t(buf);
+
+    //  MessageBox(NULL, cql, "cql 尺寸相同", MB_ICONSTOP);
+    auto sr = cdr->ActivePage->Shapes->FindShapes(_bstr_t(), cdrNoShape, VARIANT_TRUE, cql);
+    sr->CreateSelection();
+
+    strcpy(infobuf , buf);
+    return true;
+}
+
+bool Shapes_Filp(corel *cdr)
+{
+    BeginOpt(cdr);
+    auto sr = cdr->ActiveSelectionRange;
+    // CorelDRAW Shapes 物件 Item 编号从1开始
+    for (auto i = 0; i != sr->Count; i++)
+        sr->Shapes->Item[i + 1]->Flip(VGCore::cdrFlipHorizontal);
+
+    EndOpt(cdr);
+    return true;
+}
+
+bool  Clear_Fill(corel *cdr)
+{
+    cdr->ActiveSelection->Fill->ApplyNoFill();
+    return true;
+}

+ 24 - 0
09_BoundaryGroup/cdrapp.h

@@ -0,0 +1,24 @@
+#ifndef CDRAPP_H_INCLUDED
+#define CDRAPP_H_INCLUDED
+#include "cdrapi.h"
+
+bool fill_red(corel *cdr);
+bool cql_OutlineColor(corel *cdr);
+bool cql_FillColor(corel *cdr);
+bool cql_SameSize(corel *cdr);
+bool Shapes_Filp(corel *cdr);
+bool Shapes_Filp(corel *cdr);
+bool Clear_Fill(corel *cdr);
+
+void CdrCopy_to_AdobeAI(corel *cdr);
+void AdobeAI_Copy_ImportCdr(corel *cdr);
+
+bool AutoMakeSelection(corel *cdr);
+bool Box_AutoGroup(corel *cdr, double exp = 0.0);
+bool BBox_DrawRectangle(corel *cdr, double exp = 0.0);
+
+void run_BoundaryGroup(corel *cdr);
+
+extern char infobuf[];
+
+#endif // CDRAPP_H_INCLUDED

+ 60 - 0
09_BoundaryGroup/lycpg64.cbp

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="lycpg64" />
+		<Option pch_mode="2" />
+		<Option compiler="microsoft_visual_c_2022" />
+		<Build>
+			<Target title="Debug">
+				<Option output="bin/Debug/lycpg64" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Debug/" />
+				<Option type="3" />
+				<Option compiler="microsoft_visual_c_2022" />
+				<Option createDefFile="1" />
+				<Option createStaticLib="1" />
+				<Compiler>
+					<Add option="/Zi" />
+					<Add option="/D_DEBUG" />
+				</Compiler>
+				<Linker>
+					<Add option="/debug" />
+				</Linker>
+			</Target>
+			<Target title="Release">
+				<Option output="bin/Release/lycpg64" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj/Release/" />
+				<Option type="3" />
+				<Option compiler="microsoft_visual_c_2022" />
+				<Option createDefFile="1" />
+				<Option createStaticLib="1" />
+				<Compiler>
+					<Add option="/Ox" />
+					<Add option="/DNDEBUG" />
+					<Add directory="../TypeLibs" />
+				</Compiler>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="/W3" />
+			<Add option="/EHsc" />
+		</Compiler>
+		<Unit filename="BoundaryGroup.cpp" />
+		<Unit filename="ToolsBox.cpp" />
+		<Unit filename="ToolsBox.rc">
+			<Option compilerVar="WINDRES" />
+			<Option target="Release" />
+		</Unit>
+		<Unit filename="boxAutoGroup.cpp" />
+		<Unit filename="cdrPDF2Clip.cpp" />
+		<Unit filename="cdrapi.cpp" />
+		<Unit filename="cdrapi.h" />
+		<Unit filename="cdrapp.cpp" />
+		<Unit filename="cdrapp.h" />
+		<Unit filename="resource.h" />
+		<Unit filename="vbadll.cpp" />
+		<Extensions>
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>

+ 36 - 0
09_BoundaryGroup/lycpg64_build_log.html

@@ -0,0 +1,36 @@
+<html>
+<head>
+<title>lycpg64构建日志</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head>
+<body>
+<tt>
+开始构建:<u>29-08-2024 at 23:49.51</u><br />
+构建结束于:<u>29-08-2024 at 23:49.52</u><p />
+<b>-------------- 构建: Release 在 lycpg64 中 (编译器: Microsoft Visual C++ 2022)---------------</b><br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c BoundaryGroup.cpp /Foobj\Release\BoundaryGroup.obj<br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c boxAutoGroup.cpp /Foobj\Release\boxAutoGroup.obj<br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c cdrapi.cpp /Foobj\Release\cdrapi.obj<br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c cdrapp.cpp /Foobj\Release\cdrapp.obj<br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c cdrPDF2Clip.cpp /Foobj\Release\cdrPDF2Clip.obj<br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c ToolsBox.cpp /Foobj\Release\ToolsBox.obj<br />
+rc.exe /IC:\MSVC2022\include /IR:\09_BoundaryGroup  -foobj\Release\ToolsBox.res ToolsBox.rc<br />
+cl.exe /nologo /W3 /EHsc  /Ox /DNDEBUG    /I..\TypeLibs /IC:\MSVC2022\include /IR:\09_BoundaryGroup /c vbadll.cpp /Foobj\Release\vbadll.obj<br />
+BoundaryGroup.cpp<br />
+boxAutoGroup.cpp<br />
+cdrapi.cpp<br />
+cdrapp.cpp<br />
+cdrPDF2Clip.cpp<br />
+ToolsBox.cpp<br />
+vbadll.cpp<br />
+Microsoft (R) Windows (R) Resource Compiler Version 10.0.10011.16384<br />
+Copyright (C) Microsoft Corporation.  All rights reserved.<br />
+<font color="#0000ff">ToolsBox.cpp(188): warning C4311: “类型强制转换”: 从“HWND”到“LONG”的指针截断</font><br />
+<font color="#0000ff">ToolsBox.cpp(188): warning C4302: “类型强制转换”: 从“HWND”到“LONG”截断</font><br />
+link.exe /dll /nologo /LIBPATH:C:\MSVC2022\lib /out:bin\Release\lycpg64.dll Gdi32.lib user32.lib Kernel32.lib obj\Release\BoundaryGroup.obj obj\Release\boxAutoGroup.obj obj\Release\cdrapi.obj obj\Release\cdrapp.obj obj\Release\cdrPDF2Clip.obj obj\Release\ToolsBox.obj obj\Release\vbadll.obj  obj\Release\ToolsBox.res<br />
+  正在创建库 bin\Release\lycpg64.lib 和对象 bin\Release\lycpg64.exp<br />
+输出文件为 bin\Release\lycpg64.dll,大小为 229.50 KB<br />
+<font color="#0000ff">程序退出, 返回状态码:0 (0 分, 1 秒)</font><br />
+<font color="#0000ff">0个错误, 2个警告 (0 分, 1 秒)</font><br />
+</tt>
+</body>
+</html>

+ 18 - 0
09_BoundaryGroup/resource.h

@@ -0,0 +1,18 @@
+#ifndef IDC_STATIC
+#define IDC_STATIC (-1)
+#endif
+
+#define IDD_TOOLS_BOX                           100
+#define IDI_ICON1                               101
+#define IDC_CQL_FILL                            40001
+#define IDC_CQL_OUTLINE                         40002
+#define IDC_CQL_SIZE                            40003
+#define IDC_SR_FLIP                             40004
+#define IDC_CLEAR_FILL                          40005
+#define IDC_CDR2AI                              40006
+#define IDC_AI2CDR                              40007
+#define EXP_LT                                  40008
+#define EXP_TEXT                                40009
+#define INFO_TEXT                               40010
+#define IDC_BOX_GROUP                           40011
+#define ID_BOUNDARY_GROUP                       40012

+ 58 - 0
09_BoundaryGroup/vbadll.cpp

@@ -0,0 +1,58 @@
+
+#include "cdrapi.h"
+#include "cdrapp.h"
+
+extern corel *cdr;
+extern "C" __declspec(dllexport)
+int __stdcall vbadll(int code, double x =0.0){
+
+try {
+    switch(code){
+        case 1:
+            AdobeAI_Copy_ImportCdr(cdr);
+        break;
+        
+        case 2:
+            CdrCopy_to_AdobeAI(cdr);
+        break;
+
+        case 3:
+            Clear_Fill(cdr);
+        break;
+
+        case 4:
+            Shapes_Filp(cdr);
+        break;
+
+        case 5:
+            cql_FillColor(cdr);
+        break;
+
+        case 6:
+            cql_OutlineColor(cdr);
+        break;
+
+        case 7:
+            cql_SameSize(cdr);
+        break;
+
+        case 8:
+            fill_red(cdr);
+        break;
+
+        case 9:
+            BBox_DrawRectangle(cdr, x);
+        break;
+
+        case 10:
+            Box_AutoGroup(cdr, x);
+        break;
+
+        default:
+            return 0;
+    }
+} catch (_com_error &e) {
+    MessageBox(NULL, e.Description(), "Error", MB_ICONSTOP);
+}
+    return code;
+}