这样的进度条窗口是怎样弄的?

BCB 2003-02-17 08:42:48
执行一项速度较慢的操作,许多程序会弹出一个含有进度条的
小窗口,一边运行,一边进度在变化着,这不会太难,问题是
为了独占运行(封锁其它操作),人家这这个进度条小窗口可
能是用ShowModal()显示的,但用了ShowModal(),连自已的
程序也得不到控制权了,进度都没法设置了,人家是如何实现
的呢?即既是Form2->ShowModal(),也能控制进度和运行自已
的程序?









...全文
355 36 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
嘿嘿,俺的手脚比较快也。
  • 打赏
  • 举报
回复
嘿嘿,讨厌的木头。。。。:)
  • 打赏
  • 举报
回复
3:
//form2:
//.h
#define MY_MESSAGEPROCESSING WM_USER+2004
#define MY_MESSAGEFINISH WM_USER+2005
class TForm2 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TProgressBar *ProgressBar1;
private: // User declarations
void __fastcall OnMyMessageProcessing(TMessage& Message);
void __fastcall OnMyMessageFinish(TMessage& Message);
protected:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(MY_MESSAGEPROCESSING, TMessage, OnMyMessageProcessing)
VCL_MESSAGE_HANDLER(MY_MESSAGEFINISH , TMessage, OnMyMessageFinish )
END_MESSAGE_MAP(TComponent)
public: // User declarations
__fastcall TForm2(TComponent* Owner);
};
//.cpp
void __fastcall TForm2::OnMyMessageProcessing(TMessage& Message)
{
ProgressBar1->Position = Message.WParam;
}
void __fastcall TForm2::OnMyMessageFinish(TMessage& Message)
{
Button1->Enabled = true;
}
这样由线程来通知MainForm 生成form2->ShowModal,
并且在线程中刷新form2的进度条....
比较完美...:)


copy_paste 2003-02-18
  • 打赏
  • 举报
回复
哦,搞错了,那贴子没那个代码,那贴子只是给我测试用的,我刚把它用在我的一个模块上,上面的代码只是DEMO来的。
  • 打赏
  • 举报
回复
1.
//MainForm:
//.H
#define MY_MESSAGESTART WM_USER+2003
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
void __fastcall OnMyMessageStart(TMessage& Message);
protected:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(MY_MESSAGESTART, TMessage, OnMyMessageStart)
END_MESSAGE_MAP(TComponent)

public: // User declarations
__fastcall TForm1(TComponent* Owner);

};
//.cpp
//---------------------------------------------------------------------------
void __fastcall TForm1::OnMyMessageStart(TMessage& Message)
{
Form2->ShowModal();
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
MyThread* t = new MyThread(false);
}


2.
//新建一个thread:
//.cpp
#define MY_MESSAGESTART WM_USER+2003
#define MY_MESSAGEPROCESSING WM_USER+2004
#define MY_MESSAGEFINISH WM_USER+2005
__fastcall MyThread::MyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
FreeOnTerminate = true;
}
//---------------------------------------------------------------------------
void __fastcall MyThread::Execute()
{
//---- Place thread code here ----
PostMessage(Application->MainForm->Handle,MY_MESSAGESTART,0,0);
for(int x = 0; x<100; ++x)
{
Sleep(50);
PostMessage(Screen->ActiveForm->Handle,MY_MESSAGEPROCESSING,x,0);
}
PostMessage(Screen->ActiveForm->Handle,MY_MESSAGEFINISH,0,0);
}
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
哦,代码是delphi的,你看看。
http://expert.csdn.net/Expert/topic/1432/1432712.xml?temp=.1479761
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
我今天做了一个,
思路大概是这样:
mainForm是Show
progressForm是Show

MainForm中有一个Thread,是MainForm中需要一个速度慢的工作时调用的

MainForm::Work()
{
Thread = new TSomeThread(Handle, ...);
}

TSomeThread::TSomeThread(HANDLE AHandle....)
{
// 线程构造时就是禁止父窗口时。
ProgressForm = new TProgressForm(...);
ProgressForm->Show();// 它是最前面,stayOnTop
FParentHandle = AHandle;
if (IsWindowEnabled(FParentHandle))
EnableWindow(FParentHandle);
TThread::TThread(false);
}

TSomeThread::~TSomeThread()
{
//结束线程,当然要恢复父窗口啦
if (!IsWindowEnabled(FParentHandle))
EnableWindow(FParentHandle, true);
delete ProgressForm;
}

TSomeThread::Execute()
{
ProgressForm->ProgressBar1->Position = ...
// 当然我在这里再利用回调,来调用MainForm的事件,方法。。。
...
...
}

大概就是这样。
  • 打赏
  • 举报
回复
MARK...:)
BCB 2003-02-18
  • 打赏
  • 举报
回复
delphi中有人提出用Show(),
并将Form1->Enabled=false;
这点很象 ShowModal()了,
好象这里没人想到,我给了他100分
BCB 2003-02-18
  • 打赏
  • 举报
回复
非常感谢,受益非浅,发了200分,
解决的方法就是在form2中处理,
另一个就是线程,有点复杂
halibut 2003-02-18
  • 打赏
  • 举报
回复
用多线程不可以么!
  • 打赏
  • 举报
回复
嘿嘿,不要生气啦....:)
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
成心不让我睡觉,不理你啦。
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
ShowModal其实也是控制了一下EnableWindow,
ShowModal的函数已经是在取Application消息,它都使劲不返回,俺也没辄啊。。。

而且BCB说:
>>为了独占运行(封锁其它操作),人家这这个进度条小窗口可
能是用ShowModal()显示的

看到没有,是可能,俺呢,俺认为是:不是。哈哈。

...
ModalResult := 0;
//妈妈,你叫我怎么会你退出来。。
repeat
Application.HandleMessage;
if Application.FTerminate then ModalResult := mrCancel else
if ModalResult <> 0 then CloseModal;
until ModalResult <> 0;

Result := ModalResult;
...

当然有法子,可以用我上面那Form2的法子写,然后重写TForm2::ShowModal方法,ShowModal方法不要继承TForm::ShowModal,只做Show()工作,好,这样就可以了。哈哈,很纯吧。
  • 打赏
  • 举报
回复
嗬嗬,zzzZZZZ!
不纯。。。:)
人家要showModal
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
写个不是线程的,应该是这样了。

线程的问题总是很奇怪的,反正俺是依着它的性子走就是了。
:D:D:D
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
#ifndef Unit1H
#define Unit1H

#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TLabel *Label1;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};

extern PACKAGE TForm1 *Form1;

#endif


#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
TForm2 *Form = new TForm2(this, Handle);
Label1->Caption = "你动不了我吧,但我还是在动啊。。。Zizizi。。。";
Form->Show();
for (int i = 0; i < 1000; ++i)
{
Caption = i;
Sleep(40);
Application->ProcessMessages();
}
}


#ifndef Unit2H
#define Unit2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

class TForm2 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
private: // User declarations
HANDLE FParentHandle;
public: // User declarations
__fastcall TForm2(TComponent* Owner);
__fastcall TForm2(TComponent* Owner, HANDLE ParentHandle): TForm(Owner)
{
FParentHandle = ParentHandle;
if (IsWindowEnabled(FParentHandle))
EnableWindow(FParentHandle, false);
};
__fastcall ~TForm2()
{
if (!IsWindowEnabled(FParentHandle))
EnableWindow(FParentHandle, true);
};
};

#endif

#include <vcl.h>
#pragma hdrstop

#include "Unit2.h"

#pragma package(smart_init)
#pragma resource "*.dfm"

__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm2::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFree;
}
  • 打赏
  • 举报
回复
>>>>没有在线程的运行体生成,不然的话,会出现问题。我试过。

如果把Form2的Parent设置成Desktop就不会有问题了....:)
copy_paste 2003-02-18
  • 打赏
  • 举报
回复
不是在线程中生成,它在线程的构造函数中生成,还没有在线程的运行体生成,不然的话,会出现问题。我试过。

我只是提供一种方法。消息的话也行的,一般情况下,我也是用消息的多。因为我现在写的程序,那个进度条是不销毁的,它是全局使用的,只是提供了几个函数来使用,所以根本无消息可言,呵。
  • 打赏
  • 举报
回复
木头的进度窗口在线程中生成,我的是通知主窗体生成的,所以
这个进度窗体的生成和销毁是在主线程中,工作线程负责发送消息就可以了
这样是不是更好一些?
加载更多回复(16)

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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