这里只发一些 使用过程中的问题。对于一些某某功能的实现代码就不发了,很多东西网上可搜到。
记录的不多,希望对各位有用。有错误,请见谅并指正,谢谢!1、Login Form设计误区:
  代码类似这样:begin
  Application.Initialize;
  Application.MainFormOnTaskbar := False; Application.Title := 'AAAAAAAA';
  Application.CreateForm(TfrmMainMenuSF, frmMainMenuSF);
  Application.CreateForm(TfrmLogin, frmLogin);
  frmLogin.ShowModal;
  if frmLogin.ModalResult <> mrOK then
    Application.Terminate;
  else
    Application.Run;
end.在ModalResult<>mrOK的状况下,依据前面的执行过程,执行Terminate是没有意义的,是在沒有開啟message-loop情況執行的,但即使后面执行processmessage也没有用,因为只是处理了Terminated的标志而已 。
其实正确的写法,应该是需要先释放资源,因为前面有create各种form,应该是需要释放的。可以參考application.run這個方法,透過其做法可知:在程式退出message-loop時會執行DoneApplication來釋放各種資源。
所以应该改为:begin
  Application.Initialize; 
  Application.MainFormOnTaskbar := False; 
  Application.Title := 'AAAAAAA';
  Application.CreateForm(TfrmMainMenuSF, frmMainMenuSF);
  Application.CreateForm(TfrmLogin, frmLogin);
  frmLogin.ShowModal;
  if frmLogin.ModalResult <> mrOK then
  begin
    Application.ShowHint := False;//这个要保留
    Application.Destroying;
    Application.DestroyComponents;
    Application.Terminate;
  end
  else
    Application.Run;
end.
2、cxGrid使用问题记录3、理解vcl 窗口释放过程4、使用IB_Connection结合IB_Transaction处理事务应该注意的事项:
   由于IB_Transaction只是简单的封装,在事务提交或回滚后,并没有断开事务与数据库的联机(即注销事务ID在引擎中的登记信息),所以在用IB_Transaction处理一些记录后,当再用其它组件对数据库进行事务交易后,用IB_Transaction处理其中一笔前一个事务处理过的数据时,则会发生‘死锁’现象,因为此时的IB_Transaction所记录的是旧数据,因为有用其它组件进行过交易,此时IB_Transaction不能对这笔数据进行处理,必须断开此事务,即IB_Transaction.Close注销此事务的登记信息,然后重新开始事务,这样就保证了事务开始前所获得的记录是最新的,数据库引擎在接收到这样的一个新的事务请求后就立马允许操作了。

解决方案 »

  1.   

    我认为如果非必要,这个可以不要的:Application.CreateForm(TfrmMainMenuSF, frmMainMenuSF);因为你必须要先登录,然后才是权限,建立权限菜单,因此,你只要构建需要的登录窗口即可,其他要等判断登录后的情况而定,而不是一般情况下建立很多东西而不 show 出来放在后台有什么用?这样已经是设计有问题了吧?
    请教?
      

  2.   

      5、既然谈VCL,也应该说明一下VCL与windows消息的结合
        请点此
      

  3.   

    点这个,真不好用http://hi.csdn.net/space-24500-do-album-picid-491764.html
      

  4.   


    begin
      Application.Initialize;
      Application.MainFormOnTaskbar := False; Application.Title := 'AAAAAAAA';
      Application.CreateForm(TfrmMainMenuSF, frmMainMenuSF);
      Application.CreateForm(TfrmLogin, frmLogin);
      frmLogin.ShowModal;
      if frmLogin.ModalResult <> mrOK then
        Application.Terminate;
      else
        Application.Run;
    end.应该没有问题,
    Application在create的时候,通过createHandle已经把wndproc换了。
    {$IFDEF MSWINDOWS}
        FObjectInstance := Classes.MakeObjectInstance(WndProc);
    {$ENDIF}
        WindowClass.lpfnWndProc := @DefWindowProc;
        if not GetClassInfo(HInstance, WindowClass.lpszClassName, TempClass) then
        begin
          WindowClass.hInstance := HInstance;
          if Windows.RegisterClass(WindowClass) = 0 then
            raise EOutOfResources.Create(SWindowClass);
        end;
        FHandle := CreateWindow(WindowClass.lpszClassName, PChar(FTitle),
          WS_POPUP or WS_CAPTION or WS_CLIPSIBLINGS or WS_SYSMENU
          or WS_MINIMIZEBOX,
          GetSystemMetrics(SM_CXSCREEN) div 2,
          GetSystemMetrics(SM_CYSCREEN) div 2,
          0, 0, 0, 0, HInstance, nil);
        FTitle := '';
        FHandleCreated := True;
        SetWindowLong(FHandle, GWL_WNDPROC, Longint(FObjectInstance));!!
    所以
    procedure TApplication.Terminate;
    begin
      if CallTerminateProcs then PostQuitMessage(0); //产生wm_quit
    end;
    app的隐藏窗体是可以收的。另外:
    Application.CreateForm(TfrmMainMenuSF, frmMainMenuSF); fmMainMenuSF的Owner是Application
    . Application释放的时候会调用TComponent.DestroyComponents方法。
    内存释放应该没问题。不知道是不是这样,请多指教! 
      

  5.   

    Mark,学习!
    回复内容太短了! 
      

  6.   


    换句话说,application.terminate只有在application.run执行后,才有意义。否则PostQuitMessage,消息没有被提取并作后续释放动作,有何意义?另外,PostQuitMessage是给消息队列的,不是给“隐藏窗口”的,它退出application消息循环的一个通知,需要从消息队列peekmessage/getmessage才可获得。若是直接application.terminate, 那么Application如何被释放?
    其实这些资源占用都随着进程的销毁而回收。
      

  7.   

    的确不是application.wndproc处理wm_quit消息导致程序(终止)退出了。但程序的确是处理了PostQuitMessage发出的消息。或许应该说是主线程(大概是这样吧)
    好像是队列状态标志Q S _ Q U I T被设置所导致程序退出。program Project1;uses
      Forms,
      windows,
      controls,
      Unit1 in 'Unit1.pas' {Form1};{$R *.res}begin
      Application.Initialize;
      Application.Terminate;
      Application.CreateForm(TForm1, Form1);
      //Application.Run;
      while true do
      begin
        if Form1.ShowModal<>mrOK then break;
      end;
    end.所application.run注释了,程序依然会退出。 如果把Application.Terminate也同时注释掉,
    FORM1还是会显示的。
    另外:
    controls单位中的代码肯定被执行了。(正常情况下)所以frmMainMenuSF还是有机会被销毁的。
    finalization
      FreeAndNil(DockSiteList);
      DoneControls; 
      

  8.   


    program Project1;uses
      Forms,
      windows,
      controls,
      Unit1 in 'Unit1.pas' {Form1};{$R *.res}begin
      Application.Initialize;
      Application.Terminate;
      Application.CreateForm(TForm1, Form1);
      //Application.Run;
      while true do  ;
    {  begin
        if Form1.ShowModal<>mrOK then break;
      end;      }
    end.如果像上面这样子,程序不会退出。 但只要有窗口过程处理窗口消息,程序就会退出。大概好像是这样子吧。
      

  9.   

    哎,原来窗体的showmodal中会调用Application.HandleMessage;方法。
    肯定还是会收到WM_QUIT消息。
      

  10.   

    可是showmodal的窗体已经释放了啊,构建的消息循环也就不存在了
      

  11.   

    是的,但在实际的编码当中,因为单元引用顺序的关系,在结束化时,本来改在最后释放此模块时,却先释放了,而导致程序退出时,发生地址错误。
        我曾经有用了一个皮肤控件,状况如上描述。若是按照前面给的方法,模仿doneapplication做法,就解决了问题。
      

  12.   

    cxGrid 对我还是蛮有用处的,谢谢楼主分享了
      

  13.   


    顶一下。 的确是这样,是我没有考虑一些特殊的情况,满危险的。呵。  

    建议用Avan_Lau的方法直接销毁。
    另外,PostQuitMessage(0)产生的wm_quit消息的确不会被处理。(来不及处理了)
      

  14.   

    您只能输入 10000 个字符禁用UBB   内容存入剪贴板 
    每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分  
    这里发言,表示您接受了CSDN社区的用户行为准则。 
    请对您的言行负责,并遵守中华人民共和国有关法律法规,尊重网上道德。 
    转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。 
     
      

  15.   

    不错,只是感觉说的还不够详尽,message-loop这条主线还没完全打开.
    而且对于postmessage(0)这个消息最后的走向没有理出来,希望楼主可以再次整理下,期盼下次的总结