当前位置: 代码迷 >> 综合 >> aardio - 解决com组件窗口不自动刷新的问题
  详细解决方案

aardio - 解决com组件窗口不自动刷新的问题

热度:61   发布时间:2024-01-14 01:45:33.0

在 winform 中创建一个com组件,当 winform 大小改变后,com组件内容会出现一片空白现象,内容丢失,必须进行组件刷新后才会重新出现。截图如下:

原内容:

 丢失后:

尝试解决办法:

1、通过修改主窗口风格解决:

        mainForm.modifyStyle(,0x2000000/*_WS_CLIPCHILDREN*/)

        测试结果,可以解决com组件刷新问题。但出现了新问题,其他组件,如按钮,会出现问题,变成空白的了。如下图:

2、打开mainForm的双缓冲,可以解决。但会出现其他问题,注意下图组件右侧的滚动条:

3、因为经测试,出现这种情况后,手动执行 _object.Refresh() 是可以进行刷新的,所以尝试在窗口改变后自动调用此函数进行解决。先尝试定义 winform.wndproc 事件,让其收到 _WM_SIZE 消息时,自动执行 _object.Refresh() 函数进行刷新,发现没有效果。

class XXX{ctor(winform){this = winform.createEmbed("{4331220A-1077-4630-BEE3-0D7142D6ABD0}");// 处理窗口缩放时自动刷新winform.wndproc = function(hwnd,message,wParam,lParam){if message = 5/*_WM_SIZE*/{this._object.Refresh();}}}
}

4、尝试通过订阅消息解决: 当 winform 收到 _WM_SIZE 消息时,发布 refresh 消息。收到 refresh 消息后执行 _object.Refresh() ,仍然没有效果。

class XXX{ctor(winform){this = winform.createEmbed("{4331220A-1077-4630-BEE3-0D7142D6ABD0}");// 处理窗口缩放时自动刷新subscribe ("refresh",function(...){this._object.Refresh();} )winform.wndproc = function(hwnd,message,wParam,lParam){if message = 5/*_WM_SIZE*/{publish("refresh");}}}
}

  5、考虑通过线程实现, 当 winform 收到 _WM_SIZE 消息时,创建一个线程,延时100毫秒,再进行刷新:

class XXX{ctor(winform){this = winform.createEmbed("{4331220A-1077-4630-BEE3-0D7142D6ABD0}");// 处理窗口缩放时自动刷新winform.wndproc = function(hwnd,message,wParam,lParam){if message = 5/*_WM_SIZE*/{import thread..thread.invoke(function(v){import win;..win.delay(100)v._object.Refresh()},this)}}}
}

但会弹出一个错误信息框:

没有仔细研究原因,但是神奇的是,关掉这个信息框后,com刷新就变得正常了。 

6、winform 收到 _WM_SIZE 消息后,创建一个定时器,执行 _object.Refresh() 进行刷新,然后定时器立即取消。这次效果很理想,达到要求。

class XXX{ctor(winform){this = winform.createEmbed("{4331220A-1077-4630-BEE3-0D7142D6ABD0}");// 处理窗口缩放时自动刷新winform.wndproc = function(hwnd,message,wParam,lParam){if message = 5/*_WM_SIZE*/{winform.setInterval( function(){this._object.Refresh();return false; },1 )}}}
}

7、经过 @netfox 的指导,又学了一招,牛掰的:
     我觉得这已经是最好的方案了,既简单又好用,赞!!!

		winform.adjust = function( cx,cy,wParam ) {	 this._object.Refresh();};

8、给容器组件custom设置WS_CLIPCHILDREN风格,方法同第1条。但第1条是按照论坛某网友的方法给主窗口设置风格,经一鹤指导才明白,貌似方法错了,应该给容器组件设置,而不是主窗口。以下为正确方法:

mainForm.custom.modifyStyle(,0x2000000/*_WS_CLIPCHILDREN*/)