DELPHI写ActiveForm常见的一些问题

Technorati 标签: , , , ,

在写ActiveForm的时候,遇到不少问题,下面是我对于这些问题做的一个总结:

 

一、DAX错误 DAX错误是DELPHI写ActiveX存在的一个老问题了,一直以来没有一个很好的解决办法,下面的方法只是说尽可能的避免DAX错误:

1、网上流传的修改AxCtrls单元 在AxCtrls单元中,找到ParkingWindow函数,修改如下:


   
   
   1:  function ParkingWindow: HWND; 
   2:  var 
   3:    TempClass: TWndClass; 
   4:    ParkingName : String; 
   5:  begin 
   6:    Result := xParkingWindow; 
   7:    //if Result <> 0 then Exit; //注意这里被注释掉
   8:    
   9:    ParkingName := 'DAXParkingWindow_' + Format('%p', [@ParkingWindowProc]); 
  10:    FillChar(TempClass, sizeof(TempClass), 0); 
  11:    if not GetClassInfo(HInstance, PChar(ParkingName), TempClass) then 
  12:    begin 
  13:      TempClass.hInstance := HInstance; 
  14:      TempClass.lpfnWndProc := @ParkingWindowProc; 
  15:      TempClass.lpszClassName := PChar(ParkingName); 
  16:      if Windows.RegisterClass(TempClass) = 0 then 
  17:        raise EOutOfResources.Create(SWindowClass); 
  18:    end;
  19:    
  20:    xParkingWindow := CreateWindowEx(WS_EX_TOOLWINDOW, TempClass.lpszClassName, nil, 
  21:      WS_POPUP, GetSystemMetrics(SM_CXSCREEN) div 2, 
  22:    GetSystemMetrics(SM_CYSCREEN) div 2, 0, 0, 0, 0, HInstance, nil); 
  23:    SetWindowPos(xParkingWindow, 0, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOREDRAW 
  24:      or SWP_NOZORDER or SWP_SHOWWINDOW); 
  25:    Result := xParkingWindow; 
  26:  end;
2、尽量避免使用全局变量。IE对于ActiveX是创建了之后,除非整个IE关闭,不然不会释放ActiveX。多次调用同一个ActiveX,其全部变量很可能会出现不可预料的错误。 

二、释放问题 通常我们会在窗口的OnDestroy里面写释放代码,但在ActiveForm里面,窗口销毁确不会调用OnDestroy事件。通常的做法是重写ActiveForm的DoDestroy函数,如下:

   1:  procedure DoDestroy; override;//释放的代码写在这里面

三、使用GDI+的问题

我们使用的GDI+的代码,多半是由http://www.progdigy.com流传出来的,它在GDIOBJ单元的initialization和finalization节实现代码如下:

   1:  initialization
   2:  begin
   3:    // Initialize StartupInput structure
   4:    StartupInput.DebugEventCallback := nil;
   5:    StartupInput.SuppressBackgroundThread := False;
   6:    StartupInput.SuppressExternalCodecs   := False;
   7:    StartupInput.GdiplusVersion := 1;
   8:    // Initialize GDI+
   9:    GdiplusStartup(gdiplusToken, @StartupInput, nil);
  10:  end;
  11:   
  12:  finalization
  13:  begin
  14:    if assigned(GenericSansSerifFontFamily) then GenericSansSerifFontFamily.Free;
  15:    if assigned(GenericSerifFontFamily) then GenericSerifFontFamily.Free;
  16:    if assigned(GenericMonospaceFontFamily) then GenericMonospaceFontFamily.Free;
  17:   
  18:    if assigned(GenericTypographicStringFormatBuffer) then GenericTypographicStringFormatBuffer.free;
  19:    if assigned(GenericDefaultStringFormatBuffer) then GenericDefaultStringFormatBuffer.Free;
  20:   
  21:    // Close GDI +
  22:    GdiplusShutdown(gdiplusToken);
  23:  end;
  24:   

但是老的GDI+版本是存在BUG的,上面的代码在ActiveX释放的时候,会出现IE死掉的现象(此情况在VC编写的代码中同样存在)。因此我做了一些处理,注释掉上面的代码,然后在GDIOBJ单元中实现公共函数:

   1:  procedure GDIInit();
   2:    begin
   3:      // Initialize StartupInput structure
   4:      StartupInput.DebugEventCallback := nil;
   5:      StartupInput.SuppressBackgroundThread := False;
   6:      StartupInput.SuppressExternalCodecs   := False;
   7:      StartupInput.GdiplusVersion := 1;
   8:      // Initialize GDI+
   9:      GdiplusStartup(gdiplusToken, @StartupInput, nil);
  10:    end;
  11:   
  12:    procedure GDIFree();
  13:    begin
  14:      if assigned(GenericSansSerifFontFamily) then GenericSansSerifFontFamily.Free;
  15:      if assigned(GenericSerifFontFamily) then GenericSerifFontFamily.Free;
  16:      if assigned(GenericMonospaceFontFamily) then GenericMonospaceFontFamily.Free;
  17:   
  18:      if assigned(GenericTypographicStringFormatBuffer) then GenericTypographicStringFormatBuffer.free;
  19:      if assigned(GenericDefaultStringFormatBuffer) then GenericDefaultStringFormatBuffer.Free;
  20:   
  21:      // Close GDI +
  22:      GdiplusShutdown(gdiplusToken);
  23:    end;
  24:   

然后在ActiveForm的OnCreate和DoDestroy函数中进行创建和释放:

   1:  procedure TFrmMain.ActiveFormCreate(Sender: TObject);
   2:  begin
   3:    GDIInit();
   4:  end;
   5:   
   6:  procedure TFrmMain.DoDestroy;
   7:  begin
   8:    inherited;
   9:   
  10:    GDIFree();
  11:  end;

未完,待续...

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值