怎样隐藏应用程序的任务条图标

来源:计算机等级考试    发布时间:2012-08-28    计算机等级考试视频    评论

  windows启动时运行程序

  如果希望在windows启动时运行某个程序,可以通过向注册表中加信息来实现,下面就一个例子说明:
  首先在源文件(cpp)中加#include <Registry.hpp>
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  Tregistry *Reg;
  Reg=new TRegistry();
  Reg->RootKey=HKEY_LOCAL_MACHINE;
  Reg->OpenKey("SOFTWARE//MICROSOFT//WINDOWS//CURRENTVERSION//RUN",FALSE);
  Reg->WriteString("start","d://Oicq//QQ.exe");
  }

  客户/服务器远程数据传输处理技巧

  在实际的MIS系统中,远程数据库访问大多通过Modem连接,出于通信费用及速度方面的考虑,往往采用先将数据保存在本地,然后集中传送到远端的办法。远程数据传送可以有多种方案,最常见的是先将要传送的数据打包成文件,在利用文件传输形式传送到目的地,在目的地对数据恢复后添加到本地数据库中。这种方法普遍地应用于证券交易系统,其优点是速度快,并且可事先对数据压缩,更大限度地节约传送时间及费用。但这种方案也有其不足之处:由于利用文件传输机制,无法利用数据库本身的特性如完整性约束、数据一致性、回滚机制等,因此在比较复杂的数据库系统中较少采用。另一种方法是直接将两端处理成"客户/服务器"模式,将数据传送看成是向Server提交数据。由于这种方案充分利用了数据库服务器的特性,并且实际操作基本与局域网方式一致,因此本文将详细介绍这种方案。
  由于传输速度的原因,当传送大量数据时绝对不赞成逐条记录地向服务器提交数据,而应批量地向Server提交,Delphi/CBuilder中提供了一个TBatchMove控件专门用于批量传送数据,利用它可极大减少网络负担,提高传送速度。遗憾的是,TBatchMove控件只提供了简单的错误控制功能,没有提供显示传送进度、用户终止传送等重要功能。然而TBatchMove所依赖的BDE却提供了一种"回调机制"可以完成上述两个功能。所谓"回调"过程是这样的:当BDE执行某种操作时,比如从一张表向另一张表拷贝大量数据的过程中,每过一段时间(如需要显示拷贝进度时),BDE会调用一段你自己写的函数(回调函数),以帮助你更完全地控制程序。这种做法有点想DLPHI中的Event(事件)及事件处理函数--某个具体的操作动作会让VCL触发某个事件,从而调用一段你写好的事件处理函数,不同的事件会触发不同的处理函数。
  为了让BDE能正确地与你的函数协同工作,你必须事先"注册"你的函数,让BDE知道某个事件发生时应调用(回调)你的某段代码。BDE提供了一个DbiRegisterCallBack注册函数,不幸的是,BDE的联机帮助中的说明不能适合于Delphi/CBuilder,按照该说明编写的程序根本不能通过编译!笔者通过实践找到了正确使用BDE回调函数的方法,下面将详细介绍该机制的使用。BDE回调机制包含以下几个步骤:
  1)按BDE的预定格式编写你的回调函数
  2)调用DbiRegisterCallBack函数注册你的回调函数,这样当你执行相关数据库操作时就自然地触发你的回调函数。
  3)执行相关数据库操作,比如BatchMove1->Exectue();
  4)注销该回调函数
  其中最关键的是正确注册你的回调函数,因此先介绍第二步。(注册与注销都调用同一函数,只是最后一个参数略有不同)
  首先你应知道在哪类"事件"发生时调用你的回调函数,其次你应明白与该事件相关的参数及数据结构-----这一切都发生在调用DbiRegisterCallBack函数注册时,所以下面先介绍DbiRegisterCallBack的正确用法及说明:
  在原BDE帮助中该函数的原形(C)是这样的
  DBIResultDBIFNDbiRegisterCallBack(hCursor,ecbType,iClientData,iCbBufLen,pCbBuf,pfCb);
  要使用该函数必须include头文件,问题是Delphi/CBuilder中根本没有提供该文件,取而代之的是"BDE.HPP",但是在包含进该文件后程序仍然不能编译通过,因为该文件中没有DBIFN等的说明。一个简单的方法是在代码中去掉DBIFN。函数中各参数解释如下:hCursor是一个BDE中对象的句柄,如果这个参数为NULL,则表示注册的回调函数适合于所有BDE任务;第二个参数ecbType是指回调函数的触发条件的类别,有很多种类型可以选择,其中cbGENPROGRESS表示当需要显示一个长操作的进度时触发这个回调函数;第三个参数iClientData是传递给回调函数的某个数据结构的指针,在我们的例子中为NULL;第四个参数iCbBufLen是指回调Buffer的大小,该大小随第二个参数的不同而不同,比如sizeof(CBPROGRESSDesc);第五个参数pCbBuf是回调Buffer的指针,该指针类型随第二个参数变化,比如cbGENPROGRESS的数据结构是CBPROGRESSDesc;最后一个参数是回调函数的地址指针,当该参数为NULL时表示注销该类型的回调函数。关于回调函数将在稍后详细介绍。下面是注册执行长操作时显示进度的回调函数的格式:
  intrst=DbiRegisterCallBack(
  NULL,//适合于任何进程
  cbGENPROGRESS,//回调类型:显示长操作的进度
  NULL,//没有数据
  sizeof(CBPROGRESSDesc),//数据结构的大小
  &aCBBuf,//数据的内存地址
  ApiCallBackFun//回调函数的地址
  );
  接下来就应该完成第一步:编写回调函数
  在C中,回调函数应如下声明:
  CBRType__stdcallApiCallBackFun(
  CBTypeecbType,//回调类型
  intiClientData,//回调数据(指针)
  void*pCbInfo//回调数据结构指针
  )
  第一个参数是回调类型;第二个参数是回调数据,其解释同DbiRegisterCallBack的第三个参数;第三个是回调数据的指针,该数据的结构随回调类型的不同而不同。比如进度指示cbGENPROGRESS的数据结构是CBPROGRESSDesc,其定义如下:
  structCBPROGRESSDesc{
  shortiPercentDone;//进度的百分比
  charszMsg[128];//进度的文本信息
  };
  该结构的两个域同时只有一个起作用,第一个表示操作的进度百分比,当其为-1时表示第二个域起作用。第二个域用字符串表示进度信息,其格式为<String><:><Value>,比如:RecordsCopied:125
  本文主要在回调函数中完成两个工作:
  1)显示数据拷贝(BatchMove)进度
  2)提供让用户终止长时间拷贝的机制
  显示拷贝进度的代码如下:
  CBRType__stdcallApiCallBackFun(
  CBTypeecbType, //Callbacktype
  Int iClientData, //Clientcallbackdata
  void*pCbInfo //Callbackinfo/Client
  ) {
  AnsiString str;
  if(ecbType==cbGENPROGRESS){
  intj=StrToInt(((CBPROGRESSDesc*)pCbInfo)->iPercentDone);
  if(j<0) { //如果iPercentDone为-1,则分析szMsg的信息
  str=((CBPROGRESSDesc*)pCbInfo)->szMsg;intpos=str.AnsiPos(":")+1; //提取出拷贝的记录数
  //下面的代码用来在一个Form中显示拷贝进度及拷贝数量Form1->Label2->Caption=str.SubString(pos,100);
  Form1->Label2->Update();
  Form1->ProgressBar1->Position=int((str.SubString(pos,100).ToDouble()/Form1->TransNum)*100);
  Form1->ProgressBar1->Update();
  }else{
  Form1->ProgressBar1->Position=j;Form1->ProgressBar1->Update();
  }
  return cbrCONTINUE;
  //必须返回cbrCONTINUE以便让BatchMove继续,若返回cbrABORT则终止拷贝
  }
  }
  一切完成以后,每当调用长时间BDE操作(比如BatchMove1->Exectue())时都会触发该回调函数,注意在不需要时应"注销"这个回调函数。
  如果批量传送数据时间很长,则必须为用户提供终止该操作的机会,前面提到,若回调函数返回cbrABORT,则BatchMove过程立即终止。可以在Form上加上一个"停止"按钮和一个全局布尔变量isContinue,当开始拷贝时设该变量为true,当按钮按下后,设该变量为false,每次调用回调函数时检查isContinue的值,若为true则回调函数返回cbrCONTINUE让拷贝继续,否则返回cbrABORT终止拷贝。但是问题在于一旦拷贝过程开始,该进程内所有消息将被阻塞,应用程序在拷贝结束之前没有机会响应键盘、鼠标等一切消息,连屏幕刷新都不能完成,因此必须找到一种避免消息阻塞的方法。
  大家知道,Windows是靠事件(消息)驱动的,在WIN32系统中有两种消息队列:系统队列和应用程序队列,当一个程序进行一个长时间操作时,系统分配给该程序的时间片将完全用于处理该操作,换句话说,应用程序没有从它的应用程序队列中取出消息并处理的机会,这样该程序将停止一切对外部事件的响应直到该操作完成为止。具体到本文中就是程序必须等到BatchMove1->Execute()执行完毕后才能响应用户操作,因此用户将完全没有机会终止拷贝过程。
  解决的办法是:在回调函数中取出消息队列中的消息,并后台处理它们,这样用户将有机会按下终止按钮。实现的代码很简单,在回调函数中最后加入以下代码即可
  CBRType__stdcallApiCallBackFun(…){
  ……MSGamsg;
  while(PeekMessage(&amsg,NULL,0,0,PM_REMOVE)) {//从队列中取消息
  TranslateMessage(&amsg);//翻译消息
  DispatchMessage(&amsg);//分发消息
  }
  if(isContinue)
  return cbrCONTINUE;
  else
  returncbrABORT;
  }

  软件封面的实现

  1.先设置两个窗体Form1 Form2其中Form1为主窗体,Form2为动态调用窗体
  在工程文件Project1.cpp中加入如下代码:
  #include <vcl.h>
  #include "Unit2.h"
  #pragma hdrstop

  USERES("Project1.res");
  USEFORM("Unit1.cpp", Form1);
  USEFORM("Unit2.cpp", Form2);
  //---------------------------------------------------------------------------
  WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
  {
  try{
  Application->Initialize();
  Form2 = new TForm2(Application);
  Form2->Show();
  Form2->Update();
  Application->CreateForm(__classid(TForm1), &Form1);
  delete Form2;
  Application->Run();
  }
  catch (Exception &exception){
  Application->ShowException(&exception);
  }
  return 0;
  }
  2.然后在主窗体unit1.cpp中加入下面代码:
  void __fastcall TForm1::FormCreate(TObject *Sender)
  {
  unsigned long CurTime;
  unsigned long DelayTime;
  // 设置延迟时间为5秒
  DelayTime = 5000;
  CurTime = GetTickCount();
  // 在这儿可以加上应用程序的初始化过程
  unsigned long Inter;
  do{
  Inter = GetTickCount()-CurTime;
  Form2->ProgressBar1->Position = Inter*100.0/DelayTime;
  } while( Inter<DelayTime );
  }

视频学习

我考网版权与免责声明

① 凡本网注明稿件来源为"原创"的所有文字、图片和音视频稿件,版权均属本网所有。任何媒体、网站或个人转载、链接转贴或以其他方式复制发表时必须注明"稿件来源:我考网",违者本网将依法追究责任;

② 本网部分稿件来源于网络,任何单位或个人认为我考网发布的内容可能涉嫌侵犯其合法权益,应该及时向我考网书面反馈,并提供身份证明、权属证明及详细侵权情况证明,我考网在收到上述法律文件后,将会尽快移除被控侵权内容。

最近更新

社区交流

考试问答