你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
利用Windows消息向AutoCAD2000发送字符串命令
 

 

通常,当进行AutoCAD二次开发完成后,往往需要编制一个启动程序,以用来启动AutoCAD运行平台及进行一些初始化工作。对于初始化工作,如加载定制菜单、加载定制模块等,AutoCAD已经提供了相应的内置命令(built-in command),但是应用程序如何调用这些命令呢?大家知道,在二次开发中调用AutoCAD内置的命令,通常可以使用ads_command()函数。但是,这样做的前提必须是,该应用程序必须是在AutoCAD平台上运行的,因为ads_command()函数的执行代码包括在AutoCAD运行库文件中。而本文的启动程序是独立于AutoCAD而运行的Windows程序。

对于上述设想,在AutoCAD2000版本中可以通过向AutoCAD主程序发送WM_COPYDATA消息来完成。本文将提供一个例程,该例程的作用是,首先启动AutoCAD2000应用程序,然后加载定制的菜单,而加载定制菜单的命令是通过WM_COPYDATA消息来发送的。本例程采用Visual C++6.0编译通过。

一、准备阶段

本文的例程将要加载的定制菜单如下所示(对于定制AutoCAD菜单的方法,读者可参考各有关参考书或联机帮助)。下面的代码可以采用任何文本编辑器编写,保存格式为文本类型(.txt),但菜单源文件的后缀一般取.mnu

//Sample.mnu

***MENUGROUP=SAMPLE_MENU

 

***POP1

**FILE

ID_MENU_FILE                [文件(&F)]

ID_FILE_LOCATION            [新布置(&N)]

ID_FILE_LAYOUT          [打开布置(&O)]

[--]

ID_FILE_SWITCH_ACAD     [切换到Auto&CAD\tCtrl+W]^C^Cmenu ACAD

[--]

ID_FILE_EXIT                [退出(&E)]^C^C_quit

 

***POP2

**LAYOUT

ID_MENU_LAYOUT          [平面布置(&L)]

保存上述代码,并取文件名为Sample.mnu。在AutoCAD2000Command提示符下键入MENU命令加载该菜单文件。AutoCAD会提示用户是否生成相应的.mnc.mnr等文件(文件名同,只是后缀不同而已),生成的这些文件自动存放在Sample.mnu文件所在的目录下。在本例程中,将使用已编译过的菜单文件Sample.mnc。。

二、创建工程

启动Visual C++6.0。按照下述步骤创建本例程的工程,该例程为普通的Win32应用程序。

1. 选择File|New菜单命令,创建一个Win32 Application的工程,工程名称为StartACAD,如图1所示。单击OK按钮,进入下一步。

1  创建一个Win32应用程序工程

2. 在随之弹出的对话框中,选择工程类型为:A simple Win32 application,该类型的工程提供一个包含了WinMain()函数的.cpp文件;除此之外,还提供了一个stdafx.hstdafx.cpp文件,并且设置编译开关以产生一个预编译头文件。单击Finish按钮,进入下一步。

3.在随之弹出的对话框中单击OK按钮,确认所列信息即可。

三、编辑源代码

接下来,编辑源代码。该工程已经生成一个带有WinMain()函数的源文件,即StartACAD.cpp。打开该文件并添加如下代码(黑体部分):

// StartACAD.cpp : Defines the entry point for the application.

 

#include "stdafx.h"

 

//函数原型声明

void sendCommandToAutoCAD(const HWND hWndApp, const HWND hWndAcad, const LPSTR cmd);

 

//Windows程序的主函数

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

{

    // TODO: Place code here.

    //下述代码创建并注册应用程序窗口类

    char ClassName[] = "Start AutoCAD";

    WNDCLASS WndClass;

    HWND hWndACAD = NULL;

    if (!hPrevInstance)

    {

        memset(&WndClass, 0x00, sizeof(WNDCLASS));

        WndClass.style = 0;

        WndClass.lpfnWndProc = (WNDPROC)NULL;    //不需要窗口回调函数

        WndClass.cbClsExtra = 0;

        WndClass.cbWndExtra = 0;

        WndClass.hInstance = hInstance;

        WndClass.hIcon = NULL;

        WndClass.hCursor = NULL;

        WndClass.hbrBackground = NULL;

        WndClass.lpszMenuName = NULL;

        WndClass.lpszClassName = ClassName;

        RegisterClass(&WndClass);

    }

 

    //产生应用程序窗口,并返回句柄

    HWND hWndApp = CreateWindow(ClassName, "",

                    WS_OVERLAPPEDWINDOW,

                    CW_USEDEFAULT, CW_USEDEFAULT,

                    CW_USEDEFAULT, CW_USEDEFAULT,

                    NULL, NULL, hInstance, NULL);

    hWndACAD = FindWindow(NULL, "AutoCAD 2000");

    if (hWndACAD)

    {

        BringWindowToTop(hWndACAD);//AutoCAD 2000程序窗口置于顶端

        ShowWindow(hWndACAD, SW_RESTORE);

    }

    else

    {

        //启动AutoCAD 2000并获得其主程序窗口

        if( WinExec("C:\\Acad2000\\ACAD.exe", SW_SHOWNORMAL) < 32 )

        {

            MessageBox(NULL, "AutoCAD 2000启动失败!", "Message", MB_OK);

            return FALSE;

        }

        for(int num = 0; num <= 100; num++)

        {

            Sleep(500);    //暂停,释放控制权

            if((hWndACAD = FindWindow(NULL, "AutoCAD 2000")) != NULL)

                break;

        }

    }

   

    char cmdString[133];        //命令字符串变量

    //设置系统变量FILEDIA

    strcpy(cmdString, "(setq IsChanged 1) (if (= (getvar \"FILEDIA\") 1) (setvar \"FILEDIA\" 0) (setq IsChanged 0))\n");

    sendCommandToAutoCAD(hWndApp, hWndACAD, cmdString);

    //加载定制菜单

    strcpy(cmdString, "MENU\nD:\\StartACAD\\Sample.mnc\n");

    sendCommandToAutoCAD(hWndApp, hWndACAD, cmdString);

    //恢复系统变量FILEDIA

    strcpy(cmdString, "(if (= IsChanged 1) (setvar \"FILEDIA\" 1))\n");

    sendCommandToAutoCAD(hWndApp, hWndACAD, cmdString);

 

    DestroyWindow(hWndApp);

    return 0;

}

 

//该函数向AutoCAD 2000主程序发送字符串命令

void sendCommandToAutoCAD(const HWND hWndApp, const HWND hWndAcad, const LPSTR cmd)

{

    if( !hWndAcad )

        return;

    COPYDATASTRUCT cmdMsg;

    cmdMsg.dwData = (DWORD)1;

    cmdMsg.cbData = (DWORD)strlen(cmd) + 1;

    cmdMsg.lpData = cmd;

 

    SendMessageA(hWndAcad, WM_COPYDATA, (WPARAM)hWndApp, (LPARAM)&cmdMsg);

}

上述代码中的WinMain()函数为Win32应用程序的入口函数,类似于C语言DOS程序的main()函数。添加的代码程序流程是:首先检查是否已经存在AutoCAD2000的运行实例,如果已有AutoCAD2000运行,那么获取其主窗口句柄,否则运行AutoCAD2000(假定AutoCAD2000的安装目录为C:\ACAD2000\)。当AutoCAD2000启动以后,向其发送加载菜单的命令字符串。该字符串命令是采用AutoLISP语言(AutoCAD的一种二次开发语言)编写,限于篇幅,此处不再赘述。

注意:此例程假定被加载的菜单文件(Sample.mnc)存放在例程的工程目录上,即C:\StartACAD\

定义的函数sendCommandToAutoCAD(),用来向AutoCAD2000主程序发送一个字符串命令(注意:AutoCAD12.0Windows版本)使用定制的WM_ACAD消息)。字符串命令由发送的WM_COPYDATA消息捎带。发送WM_COPYDATA消息只能采用SendMessage()函数或相应的MFC类成员函数。发送WM_COPYDATA消息时,必须构造一个COPYDATASTRUCT结构变量作为消息的第二个参数,即lParamCOPYDATASTRUCT结构如下:

typedef struct tagCOPYDATASTRUCT {

    DWORD dwData;

    DWORD cbData;

    PVOID lpData;

}

COPYDATASTRUCT;

在向AutoCAD2000发送WM_COPYDATA消息时,dwData域必须置为1且为32位(DWORD型);lpData域指向将要发送的以空字符(null)结束的命令字符串,该域值可以为空(NULL);cbData域值指定该命令字符串的长度。如果dwData域值不为1lpData指向的命令字符串不以空字符结束,那么AutoCAD主程序将不会处理该消息。

保持缺省的参数设置。编译整个工程,生成StartAcad.exe,这是一个Win32应用程序。在Window98平台上运行StartAcad.exe。该程序启动AutoCAD2000并加载定制菜单(即Sample.mnc),如图2所示。

2  启动AutoCAD2000并加载定制菜单

AutoCAD2000发送WM_COPYDATA消息的关键是,正确设置WM_COPYDATA消息的各个域值;否则,消息将得不到正确处理。

(上述例程在Windows98Celron366运行通过)
  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089