InvokeHelper 跨线程访问/修改主界面控件

using System; 
using System.Collections.Generic; 
using System.Reflection; 
using System.Text; 
using System.Windows.Forms; 
 
namespace InvokerHelperDemo 

    /// <summary> 
    /// A thread-safe control invoker helper class. 
    /// </summary> 
    public class InvokeHelper 
    { 
        #region delegates 
        private delegate object MethodInvoker(Control control, string methodName, params object[] args); 
 
        private delegate object PropertyGetInvoker(Control control, object noncontrol, string propertyName); 
        private delegate void PropertySetInvoker(Control control, object noncontrol, string propertyName, object value); 
        #endregion 
 
        #region static methods 
        // helpers 
        private static PropertyInfo GetPropertyInfo(Control control, object noncontrol, string propertyName) 
        { 
            if (control != null && !string.IsNullOrEmpty(propertyName)) 
            { 
                PropertyInfo pi = null; 
                Type t = null; 
 
                if (noncontrol != null) 
                    t = noncontrol.GetType(); 
                else 
                    t = control.GetType(); 
 
                pi = t.GetProperty(propertyName); 
 
                if (pi == null) 
                    throw new InvalidOperationException( 
                        string.Format( 
                        "Can't find property {0} in {1}.", 
                        propertyName, 
                        t.ToString() 
                        )); 
 
                return pi; 
            } 
            else 
                throw new ArgumentNullException("Invalid argument."); 
        } 
 
        // outlines 
        public static object Invoke(Control control, string methodName, params object[] args) 
        { 
            if (control != null && !string.IsNullOrEmpty(methodName)) 
                if (control.InvokeRequired) 
                    return control.Invoke( 
                        new MethodInvoker(Invoke), 
                        control, 
                        methodName, 
                        args 
                        ); 
                else 
                { 
                    MethodInfo mi = null; 
 
                    if (args != null && args.Length > 0) 
                    { 
                        Type[] types = new Type[args.Length]; 
                        for (int i = 0; i < args.Length; i++) 
                        { 
                            if (args[i] != null) 
                                types[i] = args[i].GetType(); 
                        } 
 
                        mi = control.GetType().GetMethod(methodName, types); 
                    } 
                    else 
                        mi = control.GetType().GetMethod(methodName); 
 
                    // check method info you get 
                    if (mi != null) 
                        return mi.Invoke(control, args); 
                    else 
                        throw new InvalidOperationException("Invalid method."); 
                } 
            else 
                throw new ArgumentNullException("Invalid argument."); 
        } 
 
        public static object Get(Control control, string propertyName) 
        { 
            return Get(control, null, propertyName); 
        } 
        public static object Get(Control control, object noncontrol, string propertyName) 
        { 
            if (control != null && !string.IsNullOrEmpty(propertyName)) 
                if (control.InvokeRequired) 
                    return control.Invoke(new PropertyGetInvoker(Get), 
                        control, 
                        noncontrol, 
                        propertyName 
                        ); 
                else 
                { 
                    PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName); 
                    object invokee = (noncontrol == null) ? control : noncontrol; 
 
                    if (pi != null) 
                        if (pi.CanRead) 
                            return pi.GetValue(invokee, null); 
                        else 
                            throw new FieldAccessException( 
                                string.Format( 
                                "{0}.{1} is a write-only property.", 
                                invokee.GetType().ToString(), 
                                propertyName 
                                )); 
 
                    return null; 
                } 
            else 
                throw new ArgumentNullException("Invalid argument."); 
        } 
 
        public static void Set(Control control, string propertyName, object value) 
        { 
            Set(control, null, propertyName, value); 
        } 
        public static void Set(Control control, object noncontrol, string propertyName, object value) 
        { 
            if (control != null && !string.IsNullOrEmpty(propertyName)) 
                if (control.InvokeRequired) 
                    control.Invoke(new PropertySetInvoker(Set), 
                        control, 
                        noncontrol, 
                        propertyName, 
                        value 
                        ); 
                else 
                { 
                    PropertyInfo pi = GetPropertyInfo(control, noncontrol, propertyName); 
                    object invokee = (noncontrol == null) ? control : noncontrol; 
 
                    if (pi != null) 
                        if (pi.CanWrite) 
                            pi.SetValue(invokee, value, null); 
                        else 
                            throw new FieldAccessException( 
                                string.Format( 
                                "{0}.{1} is a read-only property.", 
                                invokee.GetType().ToString(), 
                                propertyName 
                                )); 
                } 
            else 
                throw new ArgumentNullException("Invalid argument."); 
        } 
        #endregion 
    } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您的 MFC 程序中没有 `Shape` 类,可以尝试使用 `IDispatch` 接口来访问 `Shape` 对象的属性和方法。以下是一个示例代码: ```c++ void ExtractPicturesFromExcel(CString strFilePath) { COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR); try { // 创建Excel应用程序对象 _Application app; if (!app.CreateDispatch(_T("Excel.Application"))) { AfxMessageBox(_T("无法启动Excel应用程序")); return; } app.SetVisible(FALSE); // 隐藏Excel窗口 // 打开Excel文件 _Workbook workbook = app.get_Workbooks().Open(strFilePath, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional, covOptional); // 遍历每个工作表 Worksheets worksheets = workbook.get_Worksheets(); for (long i = 1; i <= worksheets.get_Count(); i++) { _Worksheet worksheet = worksheets.get_Item(COleVariant(i)); // 遍历每个图形 Shapes shapes = worksheet.get_Shapes(); for (long j = 1; j <= shapes.get_Count(); j++) { // 使用 IDispatch 接口访问 Shape 对象 COleVariant covIndex(j); IDispatch* pDispShape = shapes.get_Item(covIndex).pdispVal; // 获取 Shape 对象的类型 COleVariant covType; pDispShape->InvokeHelper(DISPID_SHAPE_TYPE, DISPATCH_PROPERTYGET, VT_I4, (void*)&covType); // 判断是否为图片 if (covType.iVal == msoPicture) { // 提取图片并保存到本地 COleVariant covPictureFormat; pDispShape->InvokeHelper(DISPID_SHAPE_PICTUREFORMAT, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&covPictureFormat); COleVariant covPicturePath(L"C:\\Pictures\\" + std::to_wstring(i) + L"_" + std::to_wstring(j) + L".jpg"); covPictureFormat.pdispVal->InvokeHelper(DISPID_PICTURES_SAVEAS, DISPATCH_METHOD, VT_EMPTY, NULL, NULL, 1, &covPicturePath); } pDispShape->Release(); } } workbook.Close(covFalse, covOptional, covOptional); app.Quit(); } catch (COleException* e) { AfxMessageBox(_T("OLE异常发生")); e->Delete(); } catch (CException* e) { AfxMessageBox(_T("异常发生")); e->Delete(); } } ``` 在此示例中,我们使用 `IDispatch` 接口访问 `Shape` 对象的属性和方法。通过调用 `shapes.get_Item(covIndex).pdispVal` 获取 `Shape` 对象的 `IDispatch` 接口指针,然后使用 `InvokeHelper` 方法访问 `Shape` 对象的属性和方法。例如,我们使用 `DISPID_SHAPE_TYPE` 和 `DISPID_SHAPE_PICTUREFORMAT` 来获取 `Shape` 对象的类型和图片格式,并使用 `DISPID_PICTURES_SAVEAS` 来将图片保存到本地。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值