我的程序是一个控制台程序,其中有枚举窗口函数,运行正常,能枚举窗口并显示窗口标题,
但是我在程序中又加入了一段抓屏的程序和内存流操作后,抓屏正常,而枚举窗口却无法了。
逐步调试发现:程序枚举窗口后,用GetWindowText获取标题,开始都正常,枚举到某一个窗体时,GetWindowsText处出错,而且不提示错误,程序就死在那儿。
一旦把抓屏和内存流操作的代码去掉后,枚举就又会一切正常,两段代码之间应该没有任何关系啊?怎么会这样呢?当不加抓屏时,程序大小197k,加了后493k
百思不得其解,痛苦中,大家帮我分析一下可能的原因?
枚举代码如下(其中WinListStr为全局变量):
function EnumWindowsProc(hwnd:HWND;lParam:DWORD ):boolean; stdcall;
var
        szCaption: array[0..256] of Char;
begin
        if GetWindowText(hwnd,szCaption,sizeof(szCaption))<>0 then
          if (length(trim(szCaption))>0) and (szCaption<>'Default IME') then
                WinListStr:=WinListStr+szCaption+',';  //句柄+名称
        result:= TRUE;
end;
Function WinList:String;
begin
  WinListStr:='';
  EnumWindows(@EnumWindowsProc,0);
  Result:=WinListStr;
end;

解决方案 »

  1.   

    没有回调你也能编译通过???
    GetWindowText(hwnd,@szCaption,sizeof(szCaption))
      

  2.   

    谢谢两位回帖,这段程序单独运行是绝对没有问题的。
    抓屏单独用了一个单元,在程序中只要包含了这个单元,即使未引用其中的函数,枚举窗口过程中程序就会死去,但抓屏运行正常,没有任何问题。两个单独运行都没问题,一旦引用该单元,枚举窗口出问题。
    大家再帮我分析一下可能的原因...
    unit ScreenManage;interfaceuses
    Windows,Classes,Graphics,Forms,ZLib,SysUtils;type
      TScreenInfo = record
        DataSize: Integer;
        Host: string;
        Port: Integer;
        Verycolored:Integer;
        DrawCur:Boolean;
        AutoRefresh:Boolean;
        TransStop:Boolean;
        ClockMouse:Boolean;
        ClockKey:Boolean;
        FGX:Integer;
        FGY:Integer;
      end;
      PScreenInfo=^TScreenInfo;
      
    procedure STGetScreenToBmp(ScreenInfo:TScreenInfo;StreamName:TMemoryStream);procedure STCompareStream(STTFirstStream,STTSecondStream,STTCompareStream:TMemorystream);
    procedure STResumeStream(STTFirstStream,STTSecondStream:TMemorystream);
    procedure CompressBitmap(bmp:TMemoryStream; Data:TMemoryStream);
    procedure UnCompressBitmap(Data:TMemoryStream; bmp: TMemoryStream);implementationprocedure STGetScreenToBmp(ScreenInfo:TScreenInfo;StreamName:TMemoryStream);
    var
      STTbmp:Tbitmap;
      Cursorx, Cursory: integer;
      dc: hdc;
      STTcan: Tcanvas;
      R: TRect;
      DrawPos: TPoint;
      STTCursor: TIcon;
      hld: hwnd;
      Threadld: dword;
      mp: tpoint;
      pIconInfo: TIconInfo;
    begin
      STTbmp := Tbitmap.Create; {建立BMPMAP }
      STTcan := TCanvas.Create; {屏幕截取}
      dc := GetWindowDC(0);
      try
        STTcan.Handle := dc;
        StreamName.Position :=0;
        R := Rect(0,0,Screen.Width,Screen.Height
        STTbmp.Width := R.Right;
        STTbmp.Height := R.Bottom;
        STTbmp.Canvas.CopyRect(R, STTcan, R);
        STTbmp.SaveToStream(StreamName);
      finally
        releaseDC(0, DC);
      end;
      STTcan.Handle := 0;
      STTcan.Free;
    if ScreenInfo.DrawCur then
    begin
      GetCursorPos(DrawPos);
      STTCursor := TIcon.Create;
      getcursorpos(mp);
      hld := WindowFromPoint(mp);
      Threadld := GetWindowThreadProcessId(hld, nil);
      AttachThreadInput(GetCurrentThreadId, Threadld, True);
      STTCursor.Handle := Getcursor();
      AttachThreadInput(GetCurrentThreadId, threadld, False);
      GetIconInfo(STTcursor.Handle, pIconInfo);
      cursorx := DrawPos.x - round(pIconInfo.xHotspot);
      cursory := DrawPos.y - round(pIconInfo.yHotspot);
      STTbmp.Canvas.Draw(cursorx, cursory, STTCursor);
      DeleteObject(pIconInfo.hbmColor);
      DeleteObject(pIconInfo.hbmMask);
      STTcursor.ReleaseHandle;
      STTCursor.Free;
    end;  
    case ScreenInfo.Verycolored  of
       0:STTbmp.PixelFormat:=pf24bit;
       1:STTbmp.PixelFormat:=pf8bit;
       2:STTbmp.PixelFormat:=pf4bit;
    end;
    STTbmp.SaveToStream(StreamName);
    STTbmp.Free;
    end;
    procedure STCompareStream(STTFirstStream,STTSecondStream,STTCompareStream:TMemorystream);
    var
      I: Integer;
      P1, P2, P3: ^Char;
    begin
    STTCompareStream.Clear;
    //--------------------------------------------------
      P1 := STTFirstStream.Memory;
      P2 := STTSecondStream.Memory;
      STTCompareStream.SetSize(STTFirstStream.Size);
      P3 := STTCompareStream.Memory;  for I := 0 to STTFirstStream.Size - 1 do
      begin
        if P1^ = P2^ then
          P3^ := '0'
        else
          P3^ := P2^;
        Inc(P1);
        Inc(P2);
        Inc(P3);
      end;
    //--------------------------------------------------
    STTFirstStream.Clear;
    STTFirstStream.CopyFrom(STTSecondStream,0);
    end;procedure STResumeStream(STTFirstStream,STTSecondStream:TMemorystream);
    var
      I: Integer;
      P1, P2: ^Char;
    begin
    //---------------------------------------------
      P1 := STTFirstStream.Memory;
      P2 := STTSecondStream.Memory;  for I := 0 to STTFirstStream.Size - 1 do
      begin
        if P2^ = '0' then P2^ := p1^;
        Inc(P1);
        Inc(P2);
      end;
    //---------------------------------------------
    STTFirstStream.Clear;
    STTFirstStream.CopyFrom(STTSecondStream,0);
    STTSecondStream.Position:=0;
    end;procedure CompressBitmap(bmp:TMemoryStream; Data:TMemoryStream);
    var
       cs      : TCompressionStream;
       ms      : TMemoryStream;
    begin
    try
       ms := TMemoryStream.Create;
       cs := TCompressionStream.Create(clDefault, ms);
       bmp.SaveToStream(cs);
       cs.Free;
       ms.Position:=0;
       Data.LoadFromStream(ms);
       Ms.Free;
    except
    end;
    end;procedure UnCompressBitmap(Data:TMemoryStream; bmp: TMemoryStream);
    var
       ms    : TMemoryStream;
       buf   : pointer;
       size  : integer;
       TmpStr: String;
    begin
       SetLength(TmpStr, Data.Size);
       Move(Data.Memory^, TmpStr[1], Data.Size);   try
          DecompressBuf(@TmpStr[1], Length(TmpStr),Length (TmpStr) * 3, buf, size);
       except
       end;
       ms := TMemoryStream.Create;
       ms.Write(buf^, size);
       FreeMem(buf);
       ms.Position := 0;
       Assert(bmp<>nil);
       bmp.LoadFromStream(ms);
       ms.Free;
    end;end.