让窗体停止响应?

kmfangxun 2004-06-22 06:05:44
XP下,一个主窗体Form1为fsMDIForm,一个子窗体Form2为 fsMdiChild(已生成),现在生成 Form3 为fsStayOnTop,要求当显示 Form3 时,点击Form1或Form2时程序无反映!请问如何实现?

注:不允许用Form3->ShowModal();
...全文
193 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
kmfangxun 2004-06-24
  • 打赏
  • 举报
回复


终于搞定了,方法是在更新进度条的过程里最后加
.....
    Sleep(50);   
Application->ProcessMessages();
.....

这样钩子函数就起作用了,或者不用钩子函数,直接把Form1、Form2的Enabled属性设为false也可以。

  如果不加的话,在XP下脱离BCB的IDE环境下独立运行时,可能会导致窗体反应不正常。

 没办法,不懂的太多了,还要使劲啃书才行。 

   多谢各位!
  
   特别感谢季世平的指点!!!

   下午结帐
RBZTMcat1 2004-06-24
  • 打赏
  • 举报
回复
to jishiping(JSP 季世平) :
季老大,帮我看个简单的问题,概念问题,
谢谢!
http://community.csdn.net/Expert/topic/3115/3115601.xml?temp=.8347895
kmfangxun 2004-06-24
  • 打赏
  • 举报
回复


对啊,很妙! 谢谢季世平的帮助,我再试用一下钩子的方法。多谢!
jishiping 2004-06-24
  • 打赏
  • 举报
回复
主线程:
if (<Form3不存在>)
<创建Form3>
<创建子线程>
Form3->ShowModal();

另外,对于上面的钩子代码,我在WinXP下也测试过了,没有问题的。
kmfangxun 2004-06-24
  • 打赏
  • 举报
回复
分少点,请多包涵,我加不了分.
jishiping 2004-06-23
  • 打赏
  • 举报
回复
用钩子函数的方法,我是测试过的,你说不行,怎么个不行啊?
jishiping 2004-06-23
  • 打赏
  • 举报
回复
主线程:
if (<Form3不存在>)
<创建Form3>
Form3->ShowModal();
<创建子线程>

子线程:
void __fastcall MyThread::Execute()
{
//假设计算过程是循环
while(1) {
//计算代码
Synchronize(UpdateProcess);
}

//线程结束前,发送消息WM_CLOSE给Form3
PostMessage(Form3->Handle, WM_CLOSE, 0, 0);
}

void __fastcall MyThread::UpdateProcess()
{
//这儿是更新进度的代码,比如
Form3->ProgressBar1->Position = xxx;
}
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
To: 季世平

您的意思是这样吗:

主线程{
.......
First: 生成子线程,并判断Form3是否存在,如存在则更新进度条,最后由子线程关闭Form3;
Second: Form3->ShowModal();
.......
}



刚才按你说的用钩子函数的方法试了几次,好像还是不行,可能是我的编码什么地方不对,我再检查一下.

jishiping 2004-06-23
  • 打赏
  • 举报
回复
计算过程放在子线程里,进度窗口放在主线程里。当计算过程需要更新进度时,使用
Synchronize(UpdateProcess); //其中UpdateProcess是里自己的线程的一个成员函数
void __fastcall MyThread::UpdateProcess()
{
//这儿是更新进度的代码,比如
Form3->ProgressBar1->Position = xxx;
}
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
谢谢季世平:

   我试试!

  另外也麻烦你讲一下如何用ShowModal()显示进度好吗?非常感谢!!!

jishiping 2004-06-23
  • 打赏
  • 举报
回复
我个人觉得,还是楼主的程序设计的问题,用ShowModal()应该可以的。这个暂且不谈,我就
单纯就楼主一开始说的问题(不用ShowModal),如何让窗口永远在前面,用户不能操作其它
窗口。方法就是使用钩子,下面是Form3的代码:

#include <vcl.h>
#pragma hdrstop

#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
static HHOOK hCbtHook = NULL;
static HHOOK hMouseHook = NULL;
static long CALLBACK CBTProc(int nCode,
WPARAM wParam, LPARAM lParam)
{
if (nCode==HCBT_ACTIVATE && wParam!=
(UINT)Form3->Handle)
return 1;
return CallNextHookEx(hCbtHook, nCode,
wParam, lParam);
}

static long CALLBACK MouseProc(int nCode,
WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT* pms;

pms = (MOUSEHOOKSTRUCT*)lParam;
if (nCode<=0 && wParam!=WM_MOUSEMOVE) {
HWND hWnd = pms->hwnd;
while(hWnd && hWnd!=Form3->Handle)
hWnd = ::GetParent(hWnd);
if (hWnd==NULL) return 1;
}
return CallNextHookEx(hMouseHook, nCode,
wParam, lParam);
}

__fastcall TForm3::TForm3(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm3::FormShow(TObject *Sender)
{
if (hCbtHook == NULL)
hCbtHook = SetWindowsHookEx(WH_CBT, (FARPROC)
CBTProc, NULL, GetCurrentThreadId());
if (hMouseHook == NULL)
hMouseHook = SetWindowsHookEx(WH_MOUSE, (FARPROC)
MouseProc, NULL, GetCurrentThreadId());
}
//---------------------------------------------------------------------------
void __fastcall TForm3::FormClose(TObject *Sender, TCloseAction &Action)
{
if (hCbtHook && UnhookWindowsHookEx(hCbtHook))
hCbtHook = NULL;
if (hMouseHook && UnhookWindowsHookEx(hMouseHook))
hMouseHook = NULL;
}
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
另外,在winme和Win2000下,不存在我说的问题.
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
To: robbyzi

你说的对,是WM_ACTIVATE,我打错了,谢谢!
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
To: GeoPhoenix

主线程有一个计算过程(时间较长),所以想在Form3上放一个进度条显示进度,但是在计算期间,当用户点击Form1或Form2时,经常会导致Form3停止响应(达不到显示进度的效果).

我也试过把计算过程放在一个线程里运行,并在线程里生成显示Form3,也达不到效果(当点击Form1或Form2时).

Form3->ShowModal()后,计算过程进行不了,所以不能ShowModal().


请问有什么好的方法吗?





kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
To: henreash

我试过了,不行!
henreash 2004-06-23
  • 打赏
  • 举报
回复
简单的:form3生成时设置form1、form2的enable为false;
form3关闭的时候设置为true;
robbyzi 2004-06-23
  • 打赏
  • 举报
回复
不是WM_ACTIVE,
应该是用这个WM_ACTIVATE吧?
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
//头文件
class TfrmProgress : public TForm
{
__published: // IDE-managed Components
TLabel *LabelTiShi;
TStaticText *TextSpentTime;
TCGauge *CGaugeProgress;
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall FormShow(TObject *Sender);
private: // User declarations
int FMin,FMax;
DWORD t1,t2;
String FSpentTime;
String __fastcall GetSpenttime(DWORD t1, DWORD t2);

public: // User declarations
__fastcall TfrmProgress(TComponent* Owner,int min,int max );

void __fastcall AddProgressBy(String tishi,int Delta);

};



//程序

TfrmProgress *frmProgress;

static HHOOK hCbtHook = NULL;
static HHOOK hMouseHook = NULL;
//---------------------------------------------------------------------------
__fastcall TfrmProgress::TfrmProgress(TComponent* Owner,int min,int max )
: TForm(Owner)
{


FMin=min;
FMax=max;

CGaugeProgress->MinValue=FMin;
CGaugeProgress->MaxValue=FMax;
CGaugeProgress->Progress=0;

t1=GetTickCount();

}
//----------------------------------------------------------------------------
void __fastcall TfrmProgress::FormClose(TObject *Sender,
TCloseAction &Action)
{
if (hCbtHook && UnhookWindowsHookEx(hCbtHook))
hCbtHook = NULL;
if (hMouseHook && UnhookWindowsHookEx(hMouseHook))
hMouseHook = NULL;

Action=caFree;

}
//---------------------------------------------------------------------------
void __fastcall TfrmProgress::FormDestroy(TObject *Sender)
{
frmProgress=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TfrmProgress::AddProgressBy(String tishi,int Delta)
{

LabelTiShi->Caption=tishi;

CGaugeProgress->AddProgress(Delta);

t2=GetTickCount();

FSpentTime=GetSpenttime(t1,t2);
TextSpentTime->Caption=FSpentTime;

Update();
//frmmain->Update();
//Sleep(0);

}
//----------------------------------------------------------------------------
String __fastcall TfrmProgress::GetSpenttime(DWORD t1, DWORD t2)
{

}
//------------------------------------------------------------------------------
static long CALLBACK CBTProc(int nCode,
WPARAM wParam, LPARAM lParam)
{
if (nCode==HCBT_ACTIVATE && wParam!=
(UINT)frmProgress->Handle)
return 1;
return CallNextHookEx(hCbtHook, nCode,
wParam, lParam);
}
//------------------------------------------------------------------------------
static long CALLBACK MouseProc(int nCode,
WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT* pms;

pms = (MOUSEHOOKSTRUCT*)lParam;
if (nCode<=0 && wParam!=WM_MOUSEMOVE) {
HWND hWnd = pms->hwnd;
while(hWnd && hWnd!=frmProgress->Handle)
hWnd = ::GetParent(hWnd);
if (hWnd==NULL) return 1;
}
return CallNextHookEx(hMouseHook, nCode,
wParam, lParam);
}
//------------------------------------------------------------------------------
void __fastcall TfrmProgress::FormShow(TObject *Sender)
{

if (hCbtHook == NULL)
hCbtHook = SetWindowsHookEx(WH_CBT, (FARPROC)
CBTProc, NULL, GetCurrentThreadId());
if (hMouseHook == NULL)
hMouseHook = SetWindowsHookEx(WH_MOUSE, (FARPROC)
MouseProc, NULL, GetCurrentThreadId());

}
//------------------------------------------------------------------------------




//---------------------------------------------------------------------------
extern PACKAGE TfrmProgress *frmProgress;
kmfangxun 2004-06-23
  • 打赏
  • 举报
回复
To:季世平


主线程:
if (<Form3不存在>)
<创建Form3>
Form3->ShowModal();
<创建子线程>

Form3->ShowModal()后 <创建子线程>还能被执行吗?



 用钩子函数的方法,在显示进度条的过程中(时间别太短),我不停地点击Form1或Form2
或不停地点击Form1的Caption部分,常常导致Form3没有反应,连Form1的Caption都显示"not responed ";我是在Windows XP下试的.
 我对钩子函数的使用不是很熟,可能是我什么地方出错了,呆会儿我把程序整理一下贴出来,麻烦您帮我看一下,不胜感激! 











GeoPhoenix 2004-06-22
  • 打赏
  • 举报
回复
注:不允许用Form3->ShowModal(); 为什么?为什么舍近求远?
加载更多回复(2)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧