+发表新主题
xjq1979 发布于2006-4-25 19:28 312 次浏览 14 位用户参与讨论
跳转到指定楼层
1。建立两个目录。

   建立第一个目录 E:my_first_UG,在这个目录下建立两个新的目录:E:my_first_UGapplication和E:my_first_UGstartup。

  建立第二个目录E:my_source,用存放你的源代码。
2。设置环境变量。

再Windows中设置一个新的环境变量:UGII_USER_DIR=E:my_first_UG。
3。打开UG,进入UIStyler应用(在Application菜单的最后)。
4。设计一个对话框。

1)在"Dialog Title"一栏填入:First Dialog,按Apply(每次输入完成后,都要按Apply,为避免?嗦,以后不再提及)。
2)在"Cue"一栏输入:%……%¥%¥¥##*%*(*(*―*―((,什么都行,呵呵。
3)在&quotrefix Name"中,把CHANGE改为MY。
4)加入四个控件。String,Push Button,Label和Single Select List


编辑对话框的各个控件。

1)改变String控件的标题,标识和长度。

Label “String” -> “Input an item”.
Identifier "STR_0" -> "ITEM"
Width in... 0 -> 20


2) 改变Push Button控件的标题,标识和回调函数的名字。

Label "Push Button" -> "Import"
Identifier "ACTION_1" -> "IMPORT"
callbacks "action_1_act_cb" -> import_cb

把"Creates Dialog"激活。





3)改变Label控件的标题和single select list 的标识。改变single select list可见项的个数。

Label Label -> Items List
Identifier "LIST_2" -> "ITEM_LIST"
Number 3 -> 6.







6. 保存对话框。

点击save图标,把对话框保存在E:my_first_UGapplication目录下, 文件名位first_dlg,生成三个文件。

(现在可以推出UG乐)。


7。建立一个vc的工程。

1)把application下的*.c和*.h文件移动到E:my_source目录下(文件可以改名字)。
2)建立一个新工程,选择Win32 DLL。
3)把c源文件和头文件加入到工程中。



8。设置vc的环境。

Project -> Settings -> C/C++ -> Category ....加上头文件。



Project -> Settings -> Link....

改变输出文件名,加入连接库文件(ug17之前的库名字不同)







Tools ->Options...->Directories

Include files 和 Libray files 加入UG UFopen的路径。





打开first_dlg.c文件,找到menu script样板的位置。
复制这个样板到一个空的文本文件。
把文件保存到E:my_first_UGstartup目录下,文件名位first.men(注意后缀)。







找到 #ifdef MENUBAR_COMMENTED_OUT,

把他和他对应的 #endif 删掉。


找到#ifdef DISPLAY_FROM_USER_EXIT,
把他和他对应的#endif删掉。

找到 <enter a valid user exit here>, 把它改为ufusr。
回复

使用道具 举报

已有14人评论

xjq1979 发表于 2006-4-25 19:29:30
打开first_dlg.c,找到construct_cb的位置,在其中添加以下代码。

int MY_construct_cb ( int dialog_id,
             void * client_data,
             UF_STYLER_item_value_type_p_t callback_data)
{
  int irc;
  UF_STYLER_item_value_type_t value;
  char string[133] = "Input a string here.";
     /* Make sure User Function is available. */
     if ( UF_initialize() != 0)
          return ( UF_UI_CB_CONTINUE_DIALOG );

  value.item_id=MY_ITEM;
  value.item_attr=UF_STYLER_VALUE;
  value.value.string = string;
  irc = UF_STYLER_set_value(dialog_id, &value);
  if(irc)
  {
    char message[132];

    UF_get_fail_message(irc, message);
  }
UF_terminate ();
找到input_cb的位置,假如下面的代码。

int MY_input_cb ( int dialog_id,
             void * client_data,
             UF_STYLER_item_value_type_p_t callback_data)
{
  UF_STYLER_item_value_type_t value;
  int irc;
  char string[133];
     /* Make sure User Function is available. */
     if ( UF_initialize() != 0)
          return ( UF_UI_CB_CONTINUE_DIALOG );

   /* read your input */
    value.item_id=MY_ITEM;
  value.indicator=UF_STYLER_STRING_VALUE;
  value.item_attr=UF_STYLER_VALUE;
  UF_STYLER_ask_value(dialog_id, &value);

  strcpy(string, value.value.string);
  UF_STYLER_free_value(&value);

  /** add it to the single list */
  value.item_id=MY_ITEM_LIST;
  value.item_attr = UF_STYLER_LIST_INSERT;
  value.subitem_index = UF_STYLER_NO_SUB_INDEX;
  value.indicator = UF_STYLER_STRING_VALUE;
  value.value.string = string;
  irc = UF_STYLER_set_value(dialog_id, &value);
  if(irc)
  {
    char message[132];

    UF_get_fail_message(irc, message);
  }     UF_terminate ();
回复

使用道具 举报

xjq1979 发表于 2006-4-25 19:30:28
就是编不出来,请教一下.
回复

使用道具 举报

xjq1979 发表于 2006-4-25 19:32:05
//////////////////////////////////////////////////////////////////////////////
//
//  1.cpp
//
//  Description:
//      Contains Unigraphics entry points for the application.
//
//////////////////////////////////////////////////////////////////////////////

//  Include files
#include <uf.h>
#include <uf_exit.h>
#include <uf_ui.h>
#if ! defined ( __hp9000s800 ) && ! defined ( __sgi ) && ! defined ( __sun )
#    include <strstream>
    using std:strstream;
    using std::endl;   
    using std::ends;
#else
#    include <strstream.h>
#endif
#include <iostream.h>
#include "1.h"

//----------------------------------------------------------------------------
//  Activation Methods
//----------------------------------------------------------------------------

//  Unigraphics Startup
//      This entry point activates the application at Unigraphics startup
extern "C" DllExport void ufsta( char *param, int *returnCode, int rlen )
{
    /* Initialize the API environment */
    int errorCode = UF_initialize();

    if ( 0 == errorCode )
    {
        /* TODO: Add your application code here */

        /* Terminate the API environment */
        errorCode = UF_terminate();
    }

    /* Print out any error messages */
    PrintErrorMessage( errorCode );
}

//----------------------------------------------------------------------------
//  Utilities
//----------------------------------------------------------------------------

// Unload Handler
//     This function specifies when to unload your application from Unigraphics.
//     If your application registers a callback (from a MenuScript item or a
//     User Defined Object for example), this function MUST return
//     "UF_UNLOAD_UG_TERMINATE".
extern "C" int ufusr_ask_unload( void )
{
    return( UF_UNLOAD_UG_TERMINATE );
}

/* PrintErrorMessage
**
**     Prints error messages to standard error and the Unigraphics status
**     line. */
static void PrintErrorMessage( int errorCode )
{
    if ( 0 != errorCode )
    {
        /* Retrieve the associated error message */
        char message[133];
        UF_get_fail_message( errorCode, message );

        /* Print out the message */
        UF_UI_set_status( message );

        // Construct a buffer to hold the text.
        ostrstream error_message;

        // Initialize the buffer with the required text.
        error_message << endl
                      << "Error:" << endl
                      << message
                      << endl << endl << ends;

        // Write the message to standard error
        cerr << error_message.str();
    }
}



自己的程序插哪里怎么写??????????
回复

使用道具 举报

xjq1979 发表于 2006-4-25 19:33:15
Number 3 -> 6.
出不来,!!!!!!!!
回复

使用道具 举报

xjq1979 发表于 2006-4-25 19:35:44

V6在冷冲模具设计中的应用模具设计中的应用




www.mie168.com  2003-1-24  来源:eworks   作者:李炳  




    V6 Pro Design由一批具有15年模具实际设计和加工经验的模具专家开发。他们深知模具设计和加工的需求。V6 Pro Design完全集成于AutoCAD中环境下操作。
    V6 Pro Design全新的设计概念和关联性特征使您的模具设计效率提高60%。出错率大大减少。
    V6 Pro Design由亚洲人开发,符合亚洲人模具设计习惯,自进入中国市场以来,帮助我们的用户大大提高了效率。为更好的服务中国客户,将针对中国用户习惯进行更加全面的开发,是唯一针对中国用户专门进行开发的冷冲模具设计软件。
    V6可以完成单工序模、复合模、连续模的设计。下文就连续模应用流程与大家分享。由此可以看到应用V6以后模具设计将发生多大的变化。
    自动展开

    无须建模,通过普通的平面三视图可以进行自动展开,有的软件也有这个功能,但是,V6的操作非常的简单方便。
    比如右左图是一个比较常见的去掉标注冲压零件的三视图,用V6展开时要先去掉厚度元素。变成右右图所示。
      
     这样利用V6的自动展开功能便可以变成右下图所示的展开图。整个过程只须短短几分钟。
     
    而且,展开经验可以保存在软件里,以后你就不必查资料了,只要几个简单的操作就可以保证你的展开100%准确。值得一提的是,V6的材料表中包含材料的很多参数,比如材料的密度、强度、硬度等等,也就是说,在你选择材料后,所有参数便会留在你的图中。在你模具设计时计算其他参数时,便会用到。
    二、自动画出排样料条图

    可以尝试不同的排样方式,排样图的上方有排样的说明,
    根据工艺与材料利用率等我们选择1来做料条。
     
    在排样图上做工站的设计,各站的设计非常的灵活与快捷。。
    如果这时候你修改产品或者设计方法,只要在排样图上修改,重新生成料条即可。尤其是在你模具设计完成后,你依然可以修改料条排样,模具也会自动更新。这可是其他任何软件无法作到的。
     
    模具设计

    这里可以完全客户化,按照公司的习惯来设置,比如你常用的模架、螺栓的安装,模板的设置等,这些设置可以一次调入,调入后一次生成所有模板图。如右图(下模板)所示。简单明了。而且你还可以在客户化中加入公司常用的其他机构。如检测装置、小导柱、等等。
     
    下图是模具设计管理器,通过它你可以随时查看其他模板、总装图、侧视图、料条图。在任何一块模板上所做的设计都可以在其他关联模板上自动做出来,比如你在下模板上设计一个螺钉,定义安装关系从下模板到下模座,那么下模座上会自动生成螺钉孔。
     
    而对于冲裁、弯曲、成型工站的设计,V6也可以很方便的完成。下面是各工站设计的对话框,可以看出非常直观。只要你选择冲裁还是弯曲或者是成型,再选择要设计 的类型,压板式、加强型还是螺栓固定式。旁边会有图示。选择后就可以在所有模板上自动生成所有相关零件和孔。
    你可以通过模具设计管理器来选择你要看的模板。非常的方便。
    出图

    首先要说明的是,V6的出图并不是单向的。你还可以通过修改标注来达到修改图形的目的。而且只要修改一个尺寸其他相关尺寸自动更新,图形自动更新。无须干涉。
      
    如上图,出图时选择你要出的模板、镶块、冲子、模仁等,选择完毕后单击GO马上就会有对应的图自动生成。
    标注符合大多数企业的习惯。正如我上面提到的一样,如果在右图修改孔表的尺寸,对应的图上的孔就会自动移到对应的位置。同时其他模板上的对应孔的位置也会自动改变,孔表尺寸也会自动更新。同样,如果你修改图,孔表也会自动更新,其他模板的图、孔表也会自动更新。无须干涉。避免了人工修改的烦琐,也避免了疏忽而忘记修改对应模板。
      
    模具设计完毕,我们往往还会出材料表,来统计标准件、模板、零件的数量,以便于备料。V6提供了一个自动的工具。无须你再返回去自己数螺钉、模板。只要一个命令,全部完成。
    而且你可以有多种方式的选择,出所有零件、标准件、模板等等。
     
    其他

    V6提供了很多在模具设计中常用到的工具,比如连多义线、压力中心的确定、冲床吨位的选择、图形边角的处理、手工标注的简化、穿丝孔的自动生成等。
    线切割

    V6还提供了线切割软件,V6 WIRE方便的功能让你实现与加工的一体化方案的实现。这里不再介绍。
    由上可以看出,模具工程师在整个设计过程中,只要集中精力来考虑如何安排工站,
    如何设计机构,而剩掉了烦琐的展开计算、排样图的绘制、标准件的设计、拆图以及标注。V6的成功实施将会对冲压模具设计带来革命性的变化!
回复

使用道具 举报

xjq1979 发表于 2006-4-25 19:36:52
注塑模具标准模架的CAD 系统是模具CAD/CAE/CAM 系统的计算机辅助设计部分,是以UG作为支撑平台,在VisualC++ 集成开发环境(IDE)下利用UG/OPEN API 接口编程技术、MenuScript 菜单集成技术,开发完全集成在UG系统之中的模具CAD 系统。UG /OPEN MenuScrip 是UG 提供的用来定制菜单的专用模块,可以生成自己的菜单。注塑模具标准模架的CAD 系统的开发是基于Windows 操作系统,采用可视化编程工具Visual C++ 6.0 对现有三维CAD 软件UG 进行二次开发。C/C++ 具有良好的可移植性和可扩充性,并且UG支持C/C++ 的应用程序接口UG/OPEN API 功能非常强大。使用Visual Studio 开发的应用程序可以直接嵌入到UG 内部,加载成功后,应用程序菜单如同UG 自带功能一样,而且操作界面风格和UG 完全一致,真正地实现和UG 软件的无缝融合。UG 中的MoldWizard 包含有电子表格驱动的模架库,这些库中的模架可加入到模具的装配中,还可以依用户需要扩展这些库,进行客户化。建立模架管理的对话框来选择标准模架,而UG/ OPEN UIStyler 是UG 提供的用来创建对话框的专用模块,利用它可以生成包括文本框、按钮、列表框和单选按钮在内的对话框要素的创建,可以实现它们的任意组合,从而创建具有UG 风格的各种对话框,在存储对话框时,系统同时保存相应的C/C++ 文件,通过对C/C++ 程序的编制最后生成动态链接库文件,UG 调用动态链接库文件时将自动弹出用户定制的对话框。数据库管理系统采用Access2000 数据库。
(二)课题的研究目标
2.1 对话框的制作
UG/OPEN UIStyler 是用来开发UG 对话框的可视化对话框编辑器,其设计的对话框的方式与VisualC++很相似。用户可利用其丰富的控件和自动生成模板的特点快速制作UG 风格窗口,从而减少了开发时间。
2.2 菜单的定制
MenuScript 是UG/OPEN 的一个重要组成部分,其作用是编辑UG 菜单文件,以生成用户化的菜单。本文通过编辑纯文本的Menu 文件(菜单脚本文件)创建并修改UG 的主菜单和下拉菜单,此方法编制的菜单脚本文件的扩展名为*.men,供UG启动时调用。
2.3 应用程序的编写
UG/OPEN API 是一个C 语言调用程序工具包,应用程序员可以用它开发出直接与UG 一同运行的程序,UG/OPEN API 封装了约2000 个UG 操作的函数,几乎所有能在UG 界面上的操作都可以用UG/OPEN API 函数实现。首先,在Microsoft VisualStudio 新建一个MFC DLL,并将刚才制作对话框时生成的模板文件加入其中,这样就可以根据需要加入相应的代码,最后编译调试生产一个*.dll 文件,以供UG 启动时调用。

九、拟解决的关键问题
9.1 制定系统的具体功能,包括分析工件的工艺性、计算工艺参数并确定工艺方案、模具工作零件和标准件设计以及模具装配图、零件图及标题栏、明细表的自动生成等。
9.2 访问数据库并调用其参数
ADO(ActiveX Data Objects)是为Microsoft 最新和最强大的数据访问范例OLE DB 而设计的,是一个便于使用的应用程序接口。利用VC++.NET的数据访问接口ADO 访问由Microsoft Office Access 创建的塑料注射模标准模架各个零部件以及装配件的参数表,并调用其中的数据作为建模的参数,这样就减少了交互式输入参数的数量从而降低了参数输入的出错率。
9.3 非法参数输入
为防止出现输入参数不合法的情况,可采用程序来控制它。由以上给出的部分程序可知,一旦输入数值小于等于0 或者程序通过ADO 调用Access 中的数据库失败时系统即弹出信息窗口,出现“输入数据非法,请重新输入”的警告信息,程序对话框并不关闭,而是等待用户重新输入正确的数据。研究了如何运用UG/OPEN UIStyler 、UG/OPEN MenuScript 和UG/OPEN API 等UG 二次开发工具,以Microsoft Visual Studio 为开发环境,开发建立了一套包含零部件、装配以及工程图的三维参数化注射模标准模架库的原则和方法,以实现生成令用户满意的企业化UG 件的目的。
回复

使用道具 举报

160665 发表于 2006-4-26 13:48:58
也是二次开发
回复

使用道具 举报

xjq1979 发表于 2006-4-27 13:58:34
Win2000中文版平台:UG NX2英文版 + VC.net英文版
1.建立目录application,startup
  在D盘根目录下建立UG目录D:UG,在里面分别建立application和startup子目录
  D:UGapplication用于放置*.dll,*.ilk文件(用VS.net生成对话框资源)
             或者*.dll, *.dlg(用UG styler生成的对话框资源)
  D:UGstartup 用于放置*.men文件,实现菜单配置
2.环境变量的设置
  我的电脑->属性->环境变量
  添加变量UGII_YG_DIR,变量值为D:UG
  添加变量UGII_VENDOR_DIR,变量值为%UGII_YG_DIR%
3.启动VC.net
  New-&gtroject->MFC->MFC DLL
  输入Project名称MyProject,点击OK,其余取默认值即可。
4.在MyProject.cpp中添加下列函数:
  int DisplayDialog(CWnd* pParent);//显示非模态对话框
  extern "C" DllExport void ufusr(char *param, int *retcode, int rlen);//UG 程序入口
  extern "C" void ufusr_cleanup(void);
  extern "C"  int ufusr_ask_unload(void);
  具体代码见MyProject.cpp
5.增加对话框资源
  增加ID为IDD_DIALOG对话框,并添加ID分别为IDC_ALLERT和IDC_INPUT的BUTTON
  为对话框增加以CDialog为基类的类 CMyDlg
6.在MyProject.cpp中添加#include"MyDlg.h"
  在MyProject.h中添加UG的头文件
#include <uf.h>    //Add UG head files
#include <uf_defs.h>
#include <uf_exit.h>
#include <uf_ui.h>
#include <uf_modl.h>
  VC.net中Include地址设置:
  Tools->Option->Projects->VC++ Directories->Show Directories for->
  选择Include Files->添加相应的地址,我的地址是:
  C:Program FilesEDSUnigraphics NX 2.0UGOPEN
7.添加库文件
  在Solution Explorer中,右键点击MyProject->Add->Add Existing Item...
  选择到UGOPEN目录,我的目录为C:Program FilesEDSUnigraphics NX 2.0UGOPEN
  文件类型选择All Files(*.*),文件名称键入*.lib,点击Open
  可以全部选择出现的5个lib文件,多选了没坏事;不过我一般只选择
   libopenintpp.lib,libufun.lib和libugopenint.lib三个
8.如果生成基于对话框的类名称不是CMyDlg或者对话框ID不是IDD_DIALOG
  修改MyProject.cpp中函数DisplayDialog(CWnd* pParent)两行相应的代码:
        CMyDlg* dlg=new CMyDlg();
        BOOL ret=dlg->Create(IDD_DIALOG);
9.编译,将Debug目录下MyProject.dll,MyProject.ilk文件 copy至D:UGapplication;
  在D:UGstartup目录下建立style.men文件,具体内容见附件。
  避免每次Copy MyProject.dll,MyProject.ilk文件小技巧:
  右键点击Solution Explorer中MyProject->Property->linker->General
->Output File->你的application目录,例如我的为
D:/UG/application/MyProject.dll, 特别注意这里是"/"。
10.运行UG
   可以看见,在Help菜单前出现了YG下拉菜单,点击MyProject到目前为止已经迈出了成功的一大步。
11.添加对话框中Alert和Input Button的事件响应,均为鼠标单击产生事件响应
   在MyDlg.cpp中添加函数
void CMyDlg::OnClickedAllert();
void CMyDlg::OnBnClickedInput();
回复

使用道具 举报

xjq1979 发表于 2006-4-27 13:59:50
做过UG二次开发的都知道,在UG里做二次开发的主要界面就是对话框了,UG自己定义了一套二次开发的界面接口,即所谓的UIStyler,对于我们用惯了MFC及Windows的消息机制来说,它那点简单的事件映射,仅有的几个控件(好像连常用的树控件都没有)让我们没有发挥的余地。于是使用MFC对话框代替UG的对话框是每个从MFC进入UG二次开发的人的首先想法。关于怎么在UG中使用MFC对话框已经有文章讲过了,我这里就不再讲了。但MFC对话框的一个很大的缺点就是与UG对框的风格不统一。UG的对话框都具有统一的风格,首先,按钮都具有自己的风格,比如它的四个角是圆角,鼠标移到上面会显示一个Focus的框。然后它的所有对话框都是一级一级弹出来的,比如点击OK按钮,可能会弹出下一个对话框,而上一级对话框会隐藏掉,按Back按钮会重新返回到上一个对话框。再有,一旦有另外一个对话框弹出,当前的对话框都会隐藏或销毁。
下面就给出我的仿UG对话框风格的对话框类CHsPMEDialog,它除了实现了上面的三点UG风格外,由于UG似乎对键盘消息做了截获,如果是普通的MFC对话框,在UG内使用时一些特殊的功能键就无效了,比如TAB键、回车键、ESC都无效了。为此在我的类中,还使用了键盘钩子截获这几个按键消息并做出处理。
//-----------------------------------------------------------------------------
// 描述:可实现类似UG风格OK、Cancel、Apply按钮风格的按钮类
//    该类来自网络,稍作修改,版权归原作者所有
//-----------------------------------------------------------------------------
class CHsPMEButton : public CButton
{
// Construction
public:
CHsPMEButton();

// Attributes
public:

// Operations
public:
inline void SetNormalTopColor(COLORREF color)
{
  m_NormalColorTop = color;
}
inline void SetNormalBottomColor(COLORREF color)
{
  m_NormalColorBottom = color;
}
inline void SetActiveTextColor(COLORREF color)
{
  m_ActiveTextColor = color;
}
inline void SetNormalTextColor(COLORREF color)
{
  m_NormalTextColor = color;
}
inline void SetSelectTextColor(COLORREF color)
{
  m_SelectTextColor = color;
}
inline void SetFrameColor(COLORREF color)
{
  m_FrameColor = color;
}
inline void SetActiveColor(COLORREF color)
{
  m_ActiveColor = color;
}
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHsPMEButton)
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CHsPMEButton();

// Generated message map functions
protected:
//{{AFX_MSG(CHsPMEButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//}}AFX_MSG

void DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC);
void DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC);
void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
LONG OnMouseLeave(WPARAM, LPARAM);
BOOL m_bIsMouseMove;

COLORREF m_FrameColor;
COLORREF m_ActiveColor;

COLORREF m_ActiveTextColor;
COLORREF m_NormalTextColor;
COLORREF m_SelectTextColor;

COLORREF m_FrameHeight;
COLORREF m_FrameShadow;

COLORREF m_NormalColorTop;
COLORREF m_NormalColorBottom;

DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CHsPMEButton
CHsPMEButton::CHsPMEButton()
{
m_bIsMouseMove = 0;
m_NormalTextColor = RGB(0, 0, 0);
m_SelectTextColor = RGB(0, 0, 0);
m_ActiveTextColor = RGB(0, 0, 0);
//m_ActiveColor  = RGB(250, 180, 80);
m_ActiveColor  = RGB(255, 120, 80);
m_NormalColorTop = RGB(255, 255, 255);  // 从UG对话框中取出的颜色
m_NormalColorBottom = RGB(213, 208, 196);
m_FrameColor  = RGB(0, 64, 128);
m_FrameHeight  = RGB(230, 230, 230);
m_FrameShadow  = RGB(128, 128, 128);
}
CHsPMEButton::~CHsPMEButton()
{
}

BEGIN_MESSAGE_MAP(CHsPMEButton, CButton)
//{{AFX_MSG_MAP(CHsPMEButton)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHsPMEButton message handlers
void CHsPMEButton:rawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
//*
CDC* pDC      = CDC::FromHandle(lpDrawItemStruct->hDC);
DWORD nState  = lpDrawItemStruct->itemState;
DWORD nAction = lpDrawItemStruct->itemAction;
CRect rc   = lpDrawItemStruct->rcItem;
UINT uStyle   = DFCS_BUTTONPUSH;
pDC->SetBkMode(TRANSPARENT);
CString strText;
GetWindowText(strText);
if( nState & ODS_SELECTED )
{
  m_bIsMouseMove = 0;
  DrawFace(m_NormalColorBottom, m_NormalColorTop, rc, rc, pDC);
  DrawFrame(m_FrameShadow, m_FrameShadow, m_FrameColor, rc, pDC);
  //pDC->Draw3dRect(rc, RGB(0,0,0), RGB(0,0,0));
  pDC->SetTextColor(m_SelectTextColor);
}
else //Normal
{
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc, rc, pDC);
  DrawFrame(m_FrameHeight, m_FrameShadow, m_FrameColor, rc, pDC);
  pDC->SetTextColor(m_NormalTextColor);
}
if( m_bIsMouseMove )
{
  CRect rc2(rc);
  rc2.DeflateRect(2, 2, 2, 2);
  DrawFace(RGB(GetRValue(m_ActiveColor), GetGValue(m_ActiveColor)+100, GetBValue(m_ActiveColor)+100),
   m_ActiveColor, rc, rc, pDC);
  DrawFace(m_NormalColorTop, m_NormalColorBottom, rc2, rc, pDC);
  CBrush NullBrush;
  NullBrush.CreateStockObject(NULL_BRUSH);
  CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
  
  CPen Pen;
  Pen.CreatePen(PS_SOLID, 1, m_FrameColor);
  CPen* pOldPen = pDC->SelectObject(&ampen);
  rc.InflateRect(1,1,1,1);
  pDC->RoundRect(rc, CPoint(3, 3));
  //rc.DeflateRect(1, 1, 1, 1);
  //pDC->Draw3dRect(rc, HeightLight, ShadowLight);
  
  pDC->SelectObject(pOldPen);
  pDC->SelectObject(pOldBrush);
  pDC->SetTextColor(m_ActiveTextColor);
}

pDC->DrawText(strText, strText.GetLength(),
  &lpDrawItemStruct->rcItem, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
//*///
}
void CHsPMEButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if( m_bIsMouseMove == 0 )
{
  m_bIsMouseMove = 1;
  Invalidate();
  
  TRACKMOUSEEVENT trackmouseevent;
  trackmouseevent.cbSize = sizeof(trackmouseevent);
  trackmouseevent.dwFlags = TME_LEAVE;
  trackmouseevent.hwndTrack = GetSafeHwnd();
  trackmouseevent.dwHoverTime = HOVER_DEFAULT;
  _TrackMouseEvent(&trackmouseevent);
}

CButton::OnMouseMove(nFlags, point);
}
LONG CHsPMEButton::OnMouseLeave(WPARAM, LPARAM)
{
m_bIsMouseMove = 0;
Invalidate();
return 0;
}
void CHsPMEButton:reSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
UINT nBS = GetButtonStyle();
// Add BS_OWNERDRAW style
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
void CHsPMEButton::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
{
CPen Pen;
CPen* pOldPen = pDC->SelectObject(&Pen);

int R, G, B;
R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();

//R = R>0 ? R : -R;
//G = G>0 ? G : -G;
//B = B>0 ? B : -B;
int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
COLORREF ColMax = Top > Bottom ? Top : Bottom;
COLORREF ColMin = Top > Bottom ? Bottom: Top;
for(int i=0; i<rc.Height(); i++)
{
  ColR -= R;
  ColG -= G;
  ColB -= B;
  /*
  if( ColR >= GetRValue(ColMax) || ColR <= GetRValue(ColMin) ||
   ColG >= GetGValue(ColMax) || ColG <= GetGValue(ColMin) ||
   ColB >= GetBValue(ColMax) || ColB <= GetBValue(ColMin) )
  {
   R = G = B = 0;
  }///*/

  Pen.DeleteObject();
  Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
   
  pDC->SelectObject(&Pen);
  
  pDC->MoveTo(rc.left, rc.top+i);
  pDC->LineTo(rc.right, rc.top+i);
}
pDC->SelectObject(pOldPen);
}
void CHsPMEButton::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
{
CBrush NullBrush;
NullBrush.CreateStockObject(NULL_BRUSH);
CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
CPen Pen;
Pen.CreatePen(PS_SOLID, 1, FrameColor);
CPen* pOldPen = pDC->SelectObject(&Pen);

pDC->RoundRect(rc, CPoint(3, 3));
rc.DeflateRect(1, 1, 1, 1);
pDC->Draw3dRect(rc, HeightLight, ShadowLight);
pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}

/////////////////////////////////////////////////////////////////////////////
// CHsPMEDialog dialog
//-----------------------------------------------------------------------------
// 描述:此类可作为仿照UG UIStyler对话框的基类。它模仿了以下几种风格:
//    1、实现UG对话框的后退(Back)功能。实现方法为任何对话框在调出下一级
//   (非模式)对话框时,先隐藏自身在需要返回上一级对话框时,根据其父窗口
//   指针将其显示出来,然后隐藏或销毁自身
//    2、实现类似UG "OK"、"Apply"、"Back"、"Cancel"等按钮的XP按钮风格效果。
//    采用的方法为使用上面的CHsPMEButton作为按钮的基类
//    3、由于UG系统对键盘消息的控制,使得某些键盘消息不能发送到MFC对话框,
//    如:TAB键,ESC键,ENTER键。而这些键对于对话框来说是很重要的。
//    采用的方法为键盘钩子,对本进程(即UG进程)的键盘消息进行截获。
//    4、实现非模态对话框类似UG风格,即只要其它对话框弹出来,上一个对话框
//    就自动销毁(隐藏)。采用CBT钩子方法截获窗口创建消息。
//-----------------------------------------------------------------------------
// 注意:
// 1、在构造对话框时必须给出其父窗口指针
// 2、在初始化基类时必须指定对话框资源模板ID
// 3、对话框资源中必须提供ID为IDC_BACK的按钮
// 4、派生类必须重写OnOK及OnCancel并且调用本基类的OnOK与OnCancel
//-----------------------------------------------------------------------------
class CHsPMEDialog : public CDialog
{
DECLARE_DYNAMIC(CHsPMEDialog)    // 为了实现IsKindOf功能
// Construction
public:
CHsPMEDialog(UINT nIDTemplate, CWnd* pParent = NULL);   // standard constructor
~CHsPMEDialog();
BOOL Create(CWnd *pParent = NULL);

// Dialog Data
//{{AFX_DATA(CHsPMEDialog)
//enum { IDD = _UNKNOWN_RESOURCE_ID_ };
  // NOTE: the ClassWizard will add data members here
//}}AFX_DATA

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHsPMEDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
virtual void OnOK();
virtual void OnCancel();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CHsPMEDialog)
afx_msg void OnBack();
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
protected:
// attributes
CWnd   *m_pParent;     // 父窗口指针
HICON   m_hIcon;     // 图标
UINT   m_nTemplateID;    // 对话框资源模板ID
CHsPMEButton m_btOK;
CHsPMEButton m_btCancel;
CHsPMEButton m_btBack;
static HHOOK m_hkKeyboard;    // 键盘钩子句柄
HHOOK   m_hkCBT;     // CBT钩子句柄

//-------------------------------------------------------------------------
// 为了能判断最上层窗口是不是一个CHsPMEDialog窗口,将建立一个所有CHsPMEDialog
// 对象的链表,通过遍历链表就能知道是不是此类窗口。下面两个成员函数分别为
// 链表的头及下一个结点的指针
static CHsPMEDialog* m_spHead;
CHsPMEDialog *m_pNext;
// operations
// 键盘钩子消息的处理函数
static LRESULT CALLBACK KeyboardProc(
  int code,       // hook code
  WPARAM wParam,  // virtual-key code
  LPARAM lParam   // keystroke-message information
  );
// CBT钩子消息处理函数
static LRESULT CALLBACK CBTProc(
  int nCode,      // hook code
  WPARAM wParam,  // depends on hook code
  LPARAM lParam   // depends on hook code
  );

// 在对象列表中查找以确定指定窗口是否为CHsPMEDialog窗口
static BOOL  IsWndKindOfThis(HWND hWnd);
// 取得指定虚拟内存地址所在的模块句柄(即其内存基地址)
static HMODULE ModuleFromAddress(PVOID pv);
public:
// attributes
// operations
// 用于模仿UG的创建一个子对话框,同时隐藏父对话框
BOOL CreateChildDialog(CHsPMEDialog *pChild);
};

CHsPMEDialog* g_pHsPMEDlg = NULL;
CHsPMEDialog* CHsPMEDialog::m_spHead = NULL;
HHOOK CHsPMEDialog::m_hkKeyboard = NULL;
IMPLEMENT_DYNAMIC(CHsPMEDialog, CDialog)
CHsPMEDialog::CHsPMEDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
: CDialog(nIDTemplate, pParent)
{
//{{AFX_DATA_INIT(CHsPMEDialog)
  // NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_pParent = pParent;
m_nTemplateID = nIDTemplate;
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON_UG); // UG对话框特有图标
// 建立起链表
m_pNext = m_spHead;
m_spHead = this;
m_hkCBT = NULL;
}
CHsPMEDialog::~CHsPMEDialog()
{
// 从链表中删除本结点
CHsPMEDialog *pTemp = m_spHead;
if(pTemp == this)
{
  m_spHead = pTemp->m_pNext;
}
else
{
  for(; pTemp->m_pNext != NULL; pTemp = pTemp->m_pNext)
  {
   if(pTemp->m_pNext == this)
   {
    pTemp->m_pNext = pTemp->m_pNext->m_pNext;
    break;
   }
  }
}
}
void CHsPMEDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHsPMEDialog)
DDX_Control(pDX, IDOK, m_btOK);
DDX_Control(pDX, IDCANCEL, m_btCancel);
DDX_Control(pDX, IDC_BACK, m_btBack);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CHsPMEDialog, CDialog)
//{{AFX_MSG_MAP(CHsPMEDialog)
ON_BN_CLICKED(IDC_BACK, OnBack)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHsPMEDialog message handlers
BOOL CHsPMEDialog::Create(CWnd *pParent /* = NULL */)
{
m_pParent = pParent;
return CDialog::Create(m_nTemplateID, pParent);
}

BOOL CHsPMEDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置标题栏图标
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);

// UG的对话框的几个标准按钮没有TAPSTOP
CWnd *pWnd = NULL;
pWnd = GetDlgItem(IDOK);
if(pWnd)
{
  pWnd->ModifyStyle(WS_TABSTOP, 0);
}
pWnd = GetDlgItem(IDC_BACK);
if(pWnd)
{
  pWnd->ModifyStyle(WS_TABSTOP, 0);
}
pWnd = GetDlgItem(IDCANCEL);
if(pWnd)
{
  pWnd->ModifyStyle(WS_TABSTOP, 0);
}

g_pHsPMEDlg = this;  // 方便在静态函数成员中调用
// 设置键盘钩子
if(m_hkKeyboard == NULL)
{
  m_hkKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId());
}
if(m_hkKeyboard == NULL)
{
  TRACE("Set Keyboard Hook failed: %dn", GetLastError());
}
if(m_hkCBT == NULL)
{
  m_hkCBT = SetWindowsHookEx(WH_CBT, CBTProc, AfxGetInstanceHandle(), GetCurrentThreadId());
}
if(m_hkCBT == NULL)
{
  TRACE("Set CBT Hook Failed: %un", GetLastError());
}

return TRUE;  // return TRUE unless you set the focus to a control
               // EXCEPTION: OCX Property Pages should return FALSE
}
void CHsPMEDialog::OnOK()
{
CDialog::OnOK();
if(m_pParent)
{
  //m_pParent->DestroyWindow();
  //((CDialog*)m_pParent)->EndDialog(IDOK);
  ((CHsPMEDialog*)m_pParent)->OnOK();
}
}
void CHsPMEDialog::OnCancel()
{
CDialog::OnCancel();
if(m_pParent)
{
  //m_pParent->DestroyWindow();
  //((CDialog*)m_pParent)->EndDialog(IDCANCEL);
  ((CHsPMEDialog*)m_pParent)->OnCancel();
}
}
void CHsPMEDialog::OnBack()
{
if(m_pParent)
{
  m_pParent->ShowWindow(SW_SHOW);
}
CDialog::OnCancel();
}

BOOL CHsPMEDialog::CreateChildDialog(CHsPMEDialog *pChild)
{
BOOL bRet = FALSE;
if(pChild->GetSafeHwnd() == NULL)
{
  bRet = pChild->Create(this);
}
bRet &= ShowWindow(SW_HIDE);
bRet &= pChild->ShowWindow(SW_SHOW);
return bRet;
}
LRESULT CALLBACK CHsPMEDialog::KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
if(code == HC_ACTION && !(lParam & 0x80000000))  // 0x80000000表示keyup,即最高位为0表示keydown,为1表示keyup
{
  //TRACE("Key downn");
  CWnd *pTopWnd = CWnd::GetActiveWindow();
  if(pTopWnd && IsWndKindOfThis(pTopWnd->m_hWnd))
  {
   // 是上层窗口是CHsPMEDialog派生类窗口的键盘消息
   if(wParam == VK_TAB || wParam == VK_ESCAPE || wParam == VK_RETURN)
   {
    // 只截获tab、esc及回车键
    //g_pHsPMEDlg->PostMessage(WM_CHAR, wParam, lParam);
    //g_pHsPMEDlg->PostMessage(WM_KEYDOWN, wParam, lParam);
   }
   switch(wParam) {
   case VK_TAB:
    {
     CWnd *pWnd = pTopWnd->GetFocus();
     CWnd *pNext = pTopWnd->GetNextDlgTabItem(pWnd, FALSE);
     if(pNext)
     {
      int nCtrlID = pNext->GetDlgCtrlID();
      //TRACE("CtrlID = %dn", nCtrlID);
      pWnd = pNext;
      while(pNext && nCtrlID == IDOK || nCtrlID == IDCANCEL || nCtrlID == IDC_BACK)
      {
       // 根据UG对话框的属性,这三个按钮是没有焦点的
       pNext = pTopWnd->GetNextDlgTabItem(pNext, FALSE);
       if(!pNext || pNext == pWnd)
       {
        // 对话框上只有上述三个按钮
        return CallNextHookEx(NULL, code, wParam, lParam);
       }
       nCtrlID = pNext->GetDlgCtrlID();
       //TRACE("CtrlID = %dn", nCtrlID);
      }
      pNext->SetFocus();
     }
     //return TRUE;
    }
    break;
   case VK_ESCAPE:
    ((CHsPMEDialog*)pTopWnd)->EndDialog(IDCANCEL);
    //return TRUE;
    break;
   case VK_RETURN:
    // UG实际上并不处理回车键
    break;
   default:
    break;
   }
  }
}
return CallNextHookEx(NULL, code, wParam, lParam);
}
void CHsPMEDialog::OnDestroy()
{
CDialog::OnDestroy();
g_pHsPMEDlg = NULL;
// 销毁键盘钩子
if(m_hkKeyboard)
{
  UnhookWindowsHookEx(m_hkKeyboard);
  m_hkKeyboard = NULL;
}
if(m_hkCBT)
{
  UnhookWindowsHookEx(m_hkCBT);
  m_hkCBT = NULL;
}
}
BOOL CHsPMEDialog::IsWndKindOfThis(HWND hWnd)
{
CHsPMEDialog *pTemp = m_spHead;
BOOL bFound = FALSE;
for(; pTemp != NULL; pTemp = pTemp->m_pNext)
{
  if(pTemp->m_hWnd == hWnd)
  {
   bFound = TRUE;
   break;
  }
}
return bFound;
}
// Returns the HMODULE that contains the specified memory address
HMODULE CHsPMEDialog::ModuleFromAddress(PVOID pv)
{

MEMORY_BASIC_INFORMATION mbi;
return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
  ? (HMODULE) mbi.AllocationBase : NULL);
}
LRESULT CHsPMEDialog::CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HCBT_CREATEWND)
{
  //TRACE("A Window is being createdn");
  LPCBT_CREATEWND lpCBT = (LPCBT_CREATEWND)lParam;
  //TRACE("Window Name = %s, Class Name = %sn", lpCBT->lpcs->lpszName, lpCBT->lpcs->lpszClass);
  if((lpCBT->lpcs->style & WS_POPUP || lpCBT->lpcs->style == WS_POPUPWINDOW))
  {
   // 只对弹出窗口进行响应,而不对子窗口(WS_CHILD或WS_CHILDWINDOW)响应
   // 取得窗口处理过程内存地址
   DWORD dwUserData = ::GetWindowLong((HWND)wParam, GWL_WNDPROC);
   if(dwUserData)
   {
    HMODULE hMoudle = ModuleFromAddress((PVOID)dwUserData);
    char szUGPath[MAX_PATH] = {0}, szModulePath[MAX_PATH] = {0};
    GetModuleFileNameA(NULL, szUGPath, MAX_PATH);
    GetModuleFileNameA(hMoudle, szModulePath, MAX_PATH);
    TRACE("CreateWindow Frome Module: %sn", szModulePath);
    TRACE("Window Name: %sn", lpCBT->lpcs->lpszName);
    if(stricmp(szUGPath, szModulePath) == 0)
    {
     // 窗口处理过程位于UG EXE模块中,此窗口必定为UG特有风格窗口(UG的对话框属于此类)
     if(_tcslen(lpCBT->lpcs->lpszClass) ==0)
     {
      // 通常对话框没有指定窗口类名而使用默认的#32770(Dialog)
      if(g_pHsPMEDlg && (HWND)wParam != g_pHsPMEDlg->m_hWnd &&
       lpCBT && lpCBT->lpcs->hwndParent != g_pHsPMEDlg->m_hWnd)
      {
       // 窗口非本窗口或其子窗口
       g_pHsPMEDlg->OnCancel();
      }
     }
    }
   }
  }
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
LRESULT CHsPMEDialog::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// 不做任何事情,只是把窗口处理过程放到创建对话框的模块内存中来

return CDialog::WindowProc(message, wParam, lParam);
}
LRESULT CHsPMEDialog::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{

return CDialog::DefWindowProc(message, wParam, lParam);
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ| Archiver|手机版|小黑屋| 碧波制图网 Stonespider

Copyright © 2021-2023 Kangli Wu   All Rights Reserved.

Powered by Discuz! X3.5( 苏ICP备18011607号-1 )

快速
回复
返回
列表
返回
顶部