Екранна снимка на няколко монитора - позициониране на курсора на мишката

Имам процедура, която прави екранна снимка на монитор и по избор включва курсора на мишката в моментната снимка. Оригиналната функция беше само за един монитор. Когато рисувате курсора на мишката, той в момента се показва правилно само на главния монитор. Но не мога да разбера как да го позиционирам на друг монитор. Вижте коментарите към края на тази процедура.

procedure ScreenShot(var Bitmap: TBitmap; const MonitorNum: Integer;
  const DrawCursor: Boolean; const Quality: TPixelFormat);
var
  DC: HDC;
  C: TCanvas;
  R: TRect;
  CursorInfo: TCursorInfo;
  Icon: TIcon;
  IconInfo: TIconInfo;
  M: TMonitor;
  CP: TPoint;
begin
  M:= Screen.Monitors[MonitorNum];
  DC:= GetDC(GetDesktopWindow);
  try
    C:= TCanvas.Create;
    try
      C.Handle:= DC;
      R:= M.BoundsRect;
      Bitmap.Width:= R.Width;
      Bitmap.Height:= R.Height;
      Bitmap.PixelFormat:= Quality;
      Bitmap.Canvas.CopyRect(Rect(0,0,R.Width,R.Height), C, R);
    finally
      C.Free;
    end;
  finally
    ReleaseDC(GetDesktopWindow, DC);
  end;
  if DrawCursor then begin
    R:= Bitmap.Canvas.ClipRect;
    Icon:= TIcon.Create;
    try
      CursorInfo.cbSize:= SizeOf(CursorInfo);
      if GetCursorInfo(CursorInfo) then
      if CursorInfo.Flags = CURSOR_SHOWING then
      begin
        Icon.Handle:= CopyIcon(CursorInfo.hCursor);
        if GetIconInfo(Icon.Handle, IconInfo) then
        begin
          CP:= CursorInfo.ptScreenPos;

          //Transition mouse position...?
          CP.X:= CP.X + M.Left;
          CP.Y:= CP.Y + M.Top;  //No difference?

          Bitmap.Canvas.Draw(
            CP.X - Integer(IconInfo.xHotspot) - R.Left,
            CP.Y - Integer(IconInfo.yHotspot) - R.Top,
            Icon);
        end;
      end;
    finally
      Icon.Free;
    end;
  end;
end;

Как да преместя правилно позицията на мишката в зависимост от монитора, който използвам?


person Jerry Dodge    schedule 02.06.2013    source източник


Отговори (1)


Нанасяте екранна координата MonitorRect.Left към растерна координата 0. И по същия начин, MonitorRect.Top до 0. Така че, ако позицията на курсора на екрана е CursorPos, тогава вие нанасяте това на CursorPos.X - MonitorRect.Left и CursorPos.Y - MonitorRect.Top. И тогава трябва да отчетете и горещата точка, но изглежда вече знаете как да направите това.

Съпоставянето по-горе се прилага еднакво за всички монитори.

Обърнете внимание, че използвах моя собствена нотация, защото намерих вашите еднобуквени променливи за грешни. Да не говорим за факта, че значението на тези променливи се променя по време на функцията. Гледам те, R. Това винаги е рецепта за болка.

Също така, не е ли необходимо да изтриете манипулаторите на растерни изображения, които ви се подават, когато се обадите на GetIconInfo? И малко проверка за грешки няма да е излишно.

person David Heffernan    schedule 02.06.2013
comment
Ааа, добре, + трябваше да бъде -, който го направи. И не работи, ако премахнете тези 2 реда - това кара курсора да се показва само ако курсорът е на главния монитор, но не и на действителния монитор, от който е екранната снимка. - person Jerry Dodge; 03.06.2013
comment
О, виждам, използвахте R два пъти! Стойността на R е правоъгълната растерна графика, която винаги е закотвена на 0,0. - person David Heffernan; 03.06.2013
comment
Е, струваше си рециклирането, тъй като началото на if DrawCursor then begin бележи началото на различен блок код. Ето защо го оставих с кратко име като R. - person Jerry Dodge; 03.06.2013
comment
@Jerry Наличието на променливи, които не са именувани и приемат различни значения в различно време, прави по-трудно четенето на кода. Това е моят съвет към вас. Вземи го или го остави. - person David Heffernan; 03.06.2013