Dll中让主程序中窗体Show的一个秒解。活用SendMessage。

    今天遇到一个需求:在一个dll中让主程序中的某个窗口显示出来。该窗口上还有很多复杂的控件。
    开始,我直接把TForm类型(VCL类型)封装到了dll中,然后用Form->Show()即可,结果在dll的去勾选build with runtime package时,编译通不过,因为使用了VCL类型时,必须使用一些vcl包进行编译。而如果勾选了build with runtime package,则不能在其他的机子上使用该dll了。

    于是这种方法行不通。(如果哪位仁兄有打包含VCL的DLL的例子,并且dll体积不大的话,一定要告诉我)后来我又使用了API函数ShowWindow,结果不如人意,因为这个函数使用极为复杂,仅适合于单窗体的操作,对于含有很多复杂控件的窗体来说,仅仅使用ShowWindow(HWND)是不行的,而且传入dll的参数自然是越少越好。
    最后,一个想法在我脑中诞生,在windows操作系统中,我觉得最强大的指令之一SendMessage几乎是万能的。在dll中只要知道了窗体的句柄,则可以向其发送任何消息。但是,如果单纯的发送SendMessage(HWND,WM_SHOWWINDOW,wp,lp)有用吗,答案是否定的,这和ShowWindow方法如出一辙。

   但是我们可以通过发送一个特定的消息A,当目标窗体接受到该特定消息A时,就调用Form->Show()函数。这时,可能大部分人想到的是使用自定义消息。可我懒得去查如何注册和使用自定义消息了(自己写过,总结在札记里)。那不使用自定义消息,又如何做呢。
   消息是死的,参数是活的,说到这,肯定大家知道怎么做了。对,我们就使用已知消息WM_SHOWWINDOW,然后把它的wp,lp参数设置的奇怪点,让目标窗体的WndProc消息循环函数判断一下就行了。我使用的消息是这样的:

Dll中:


SendMessage(pwindow,WM_SHOWWINDOW,-1,-1);//使用两个-1来做为奇怪的参数。

 

窗体的WndProc中:

 

if(Msg.Msg==WM_SHOWWINDOW)
       {
          if(Msg.WParam==-1&&Msg.LParam==-1)
          {
            Show();
            return;
          }
       }


使用了如上方法后,就可以把dll中的#include<vcl.h>删除了,而且去掉勾选build with runtime package也可以成功build了。这样就不需要用到vcl60.bpl和其他库了。程序立马小了2-5M。通过这个例子,告诉自己和大家,API是死的,但是人是活的,很多功能并不需要多强大的技术,用好现有的API,也许就能取得效率和功能上的双赢,毫不逊色于其他技术。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Android ,可以使用 Handler 和 Thread 来实现子线程更新主界面的功能。具体实现步骤如下: 1. 定义一个 Handler 对象,用于在子线程更新主界面。在主线程创建 Handler 对象,然后重写 handleMessage() 方法,该方法会在子线程执行。 ``` Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // 在此更新主界面 } }; ``` 2. 定义一个 Runnable 对象,在子线程执行需要更新主界面的操作。在该对象的 run() 方法发送消息给 Handler。 ``` Runnable updateRunnable = new Runnable() { @Override public void run() { // 执行需要更新主界面的操作 int count = 0; while (count < 60) { count++; // 模拟每秒更新一次数据 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 发送消息到 Handler,更新主界面 Message message = handler.obtainMessage(); message.what = UPDATE_VIEW; message.arg1 = count; handler.sendMessage(message); } } }; ``` 3. 在 Activity 创建子线程并启动。在子线程调用 Runnable 对象的 run() 方法。 ``` Thread thread = new Thread(updateRunnable); thread.start(); ``` 完整代码示例: ``` public class MainActivity extends AppCompatActivity { private static final int UPDATE_VIEW = 1; private TextView mTextView; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case UPDATE_VIEW: int count = msg.arg1; mTextView.setText("Count: " + count); break; default: break; } } }; private Runnable mUpdateRunnable = new Runnable() { @Override public void run() { int count = 0; while (count < 60) { count++; // 模拟每秒更新一次数据 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 发送消息到 Handler,更新主界面 Message message = mHandler.obtainMessage(); message.what = UPDATE_VIEW; message.arg1 = count; mHandler.sendMessage(message); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = findViewById(R.id.text_view); Thread thread = new Thread(mUpdateRunnable); thread.start(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值