我在DLL里定义一个鼠标钩子,可是在鼠标点击某些窗口后,会报内存异常,通常是点了某个窗口之后的时候,就报错误,显示“指定内存引用0xxxxxx ,该内存不能written”我的系统是xp,用的是delphi2006。大家指点一下,到底是什么原因,急死我了。 
先谢谢大家了。

解决方案 »

  1.   

    我的代码是这样的:
    unit unithook;interface
    uses windows,Messages,Udllconst,SysUtils,Graphics,Classes,Dialogs;var
    h: HHook;
    hMappingFile: THandle;
    PShMem: PShareMem;function StartHook(sender: HWND;messageID: LongInt):boolean;stdcall;
    function StopHook:boolean;stdcall;implementationfunction hookproc(nCode: Integer;wParam: WPARAM;lParam: LPARAM):LRESULT;stdcall;
    var
      aRect,R :TRect;//reRect: TRect;
      dc: hdc;
      Mycan: TCanvas;
      Mybmp: TBitmap;
    begin
      Result := 0;
      if nCode < 0 then
        Result := CallNextHookEx(h,nCode,wparam,lparam);
      case wparam of
        WM_LBUTTONDOWN,WM_NCLBUTTONDOWN :
          begin
            if pShMem^.data1[1] = pMOUSEHOOKSTRUCT(lparam)^.hwnd then
                  exit;
            if not pShMem^.SeCapBMP then
              begin
                
                if (pMOUSEHOOKSTRUCT(lparam)^.pt.X > pShMem^.SeRect.Left)  and
                   (pMOUSEHOOKSTRUCT(lparam)^.pt.X < pShMem^.SeRect.Right) and
                   (pMOUSEHOOKSTRUCT(lparam)^.pt.Y > pShMem^.SeRect.Top)   and
                   (pMOUSEHOOKSTRUCT(lparam)^.pt.Y < pShMem^.SeRect.Bottom) then
                  begin
                    //Showmessage('222');
                    pShMem^.data2:=pMOUSEHOOKSTRUCT(lparam)^;
                    aRect := Rect(pShMem^.SeRect.Left+3,pShMem^.SeRect.Top+3,pShMem^.SeRect.Right-2,pShMem^.SeRect.Bottom-2);
                    Mybmp := Tbitmap.Create;
                    if (pShMem^.MyHandle =0)or(pShMem^.MyHandle <> pShMem^.data2.hwnd) then
                      begin
                        //reRect := Rect(aRect.Left-3,aRect.Top-3,aRect.Right+3,arect.Bottom+3);
                        //ShowMessage('111');
                        Mycan := TCanvas.Create;
                        dc := GetWindowDC(0);
                        try
                          Mycan.Handle := dc;
                          Mybmp.Width := aRect.Right - aRect.Left;
                          Mybmp.Height := aRect.Bottom - aRect.Top;
                          R := Rect(0,0,Mybmp.width,Mybmp.Height);
                          Mybmp.Canvas.CopyRect(R, Mycan,aRect);
                        finally
                          releaseDC(0, DC);
                        end;
                        Mycan.Handle := 0;
                        Mycan.Free;
                        Inc(pShMem^.BMPIndex);
                        pShMem^.MyHandle := pShMem^.data2.hwnd;
                      end
                    else
                      Mybmp.LoadFromFile('D:\program\DemoCreator截屏预研\output\copy'+IntToStr(pShMem^.BMPIndex)+'.BMP');
                    Mybmp.Canvas.Pen.Color := clBlue;
                    Mybmp.Canvas.Brush.Style := BsClear;
                    Mybmp.Canvas.Rectangle(Rect(pShMem^.data2.pt.X-aRect.Left-3,pShMem^.data2.pt.Y-aRect.Top-3,pShMem^.data2.pt.X-aRect.Left+28,pShMem^.data2.pt.Y-aRect.Top+15));
                    Mybmp.Canvas.TextOut(pShMem^.data2.pt.X-aRect.Left,pShMem^.data2.pt.Y-aRect.Top,'Click');
                    Mybmp.SaveToFile('D:\program\DemoCreator截屏预研\output\copy'+IntToStr(pShMem^.BMPIndex)+'.BMP');
                    Mybmp.Free;
                  end;
              end;
      end;
    end;function StartHook(sender: HWND;messageID: LongInt):boolean;stdcall;
    begin
    Result := false;
    if h = 0 then
      begin
        pShMem^.data1[1]:=sender;
        pShMem^.data1[2]:=messageid;
        h := SetWindowsHookEx(WH_MOUSE,@hookProc,Hinstance,0);
        Result := true;
      end;
    end;function StopHook:boolean;stdcall;
    begin
    Result := false;
    if h <> 0 then
      begin
        UnHookWindowsHookEx(h);
        h := 0;
        Result := true;
      end;
    end;Initialization
      hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName);
      if hMappingFile=0 then
        hMappingFile := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShareMem),MappingFileName);
      if hMappingFile=0 then Exception.Create('不能建立共享内存!');
        pShMem :=  MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0);
      if pShMem = nil then
        begin
          CloseHandle(hMappingFile);
          Exception.Create('不能映射共享内存!');
        end;
      h := 0;
      pShMem^.MyHandle := 0;
      pShMem^.BMPIndex := 0;finalization
      try
        UnMapViewOfFile(pShMem);
        //pShMem := nil;
        CloseHandle(hMappingFile);
        //hMappingFile := 0;
      except
        ShowMessage('problem!');
      end;
    end.