Как я могу очистить TCanvas? Или любое другое решение

Я использую этот TCanvas для рисования курсоров для своих мышей.

Canv := TCanvas.Create;
Canv.Handle := GetWindowDC(0);

.... Для каждого события мыши сделайте следующее

Bitmap:=TBitmap.Create;
CursorInfo.cbSize := sizeof(CursorInfo);
GetCursorInfo(CursorInfo);

Bitmap.Width := 32;
Bitmap.Height := 32;
Bitmap.Transparent:=true;

DrawIconEx(Bitmap.Canvas.Handle, 0,0, CursorInfo.hCursor, 32,32, 0,0, DI_NORMAL) ;

Bitmap.Canvas.Brush.Color := RGB(250,250,250);
Bitmap.Canvas.FloodFill(31,0, clWhite, fsSurface);
Bitmap.Canvas.FloodFill(0,0, clWhite, fsSurface);

currentX:=getcurrentxpos;
currentY:=getcurrentypos;

Canv.Draw(currentX,currentY,Bitmap);
Bitmap.Free;

Проблема в том, что вместо того, чтобы просто показывать отдельные курсоры, он делает следы мыши. Могу ли я очистить весь холст каждый раз, когда мышь перемещается? (хотя звучит не очень хорошо). Может быть, я мог бы очистить свой предыдущий Canv.Draw, выполнив обратный код (если это возможно)? Любые предложения относительно того, как я могу показать курсоры?

РЕДАКТИРОВАТЬ: попытался вставить еще один Canv.Draw(currentX,currentY,Bitmap); сразу после установки ширины и высоты растрового изображения ... и теперь проблема в том, что у меня есть белый след (а не след мыши), намного чище, но все равно бесполезно.


person Dian    schedule 12.07.2010    source источник


Ответы (3)


Вы рисуете на DESKTOP, а этого никогда не следует делать, потому что это ненадежно. Насколько я понимаю, вы надеетесь найти способ нарисовать курсор мыши на рабочем столе, а когда мышь снова начнет двигаться, «отменить» последнюю краску и перекрасить мышь в новых координатах. Представьте себе: вы двигаете мышью где-то над полем для заметок, кладете руки на клавиатуру, что-то печатаете, а затем снова двигаете мышью. Изображение под мышками изменилось!

Что вы можете сделать: Создайте форму в форме курсора мыши, для этого есть известные методы. Сделайте так, чтобы ваш псевдокурсор оставался сверху (с этим у вас тоже возникнут проблемы, потому что Windows больше не любит, когда все остается сверху). Это будет нелегко, но это выполнимо, и это ИГРА ПО ПРАВИЛАМ.


Небольшой обзор кода того, что у вас уже есть, потому что я заметил ошибку, о которой вам следует знать. Исправить это недостаточно, чтобы решить вашу проблему, вам нужно перестать рисовать на рабочем столе:

Не освобождайте растровое изображение, содержащее прозрачное изображение курсора, сохраните его на всю жизнь приложения: вы сэкономите как ОЗУ, так и ЦП. Это очень важно для чего-то, что должно реагировать на движение мыши.

person Cosmin Prund    schedule 12.07.2010
comment
О, да, спасибо, я решил поместить код «формирования курсора» в FormCreate и Bitmap.Free в FormDestroy. Если я использую формы, являются ли координаты X, Y холста эквивалентными верхним и левым атрибутам формы? - person Dian; 12.07.2010
comment
Я не понимаю вашего вопроса :( Я предлагаю использовать TForm для мыши. Начните с обычного квадратного TForm, а когда это сработает, превратите его в курсор мыши. Простое кэширование растрового изображения не сильно поможет. , потому что вы не можете контролировать, кто что записывает на рабочий стол. - person Cosmin Prund; 12.07.2010
comment
О, извините, если я не ясно выразился, я имел в виду позиционирование формы. Как я могу его позиционировать? Должен ли я использовать атрибуты top и left? (Я упомянул координаты x и y холста, потому что мне было интересно, похожи ли они). и еще одно, если формы в форме курсора находятся сверху, может ли фокус по-прежнему быть на моей основной форме? Спасибо за вашу помощь. :D - person Dian; 12.07.2010
comment
Вы перемещаете форму, используя Left и Top. Вам нужно будет принять во внимание горячую точку курсора (для обычного курсора со стрелкой горячая точка находится в верхнем левом углу, прямо на кончике стрелки; для курсора I, используемого для редактирования, я думаю горячая точка находится в середине I; не знаю о других и не знаю, как читать это программно). Для формы, которую вы будете использовать (без границ), рисование начинается сверху и слева. И, наконец, форме в форме курсора не нужно захватывать фокус. - person Cosmin Prund; 12.07.2010
comment
У меня небольшие проблемы с превращением его в курсор... но в остальном он отлично работает. Спасибо! :D - person Dian; 12.07.2010
comment
@Dian, посмотри сюда: stackoverflow.com/questions/2979125/ - person Cosmin Prund; 12.07.2010
comment
Спасибо, но я нашел исходный код, который превращает форму в изображение по вашему выбору. Чертовски круто. Если бы мне не сказали, я бы никогда не подумал, что это возможно. Так что еще раз спасибо. :D - person Dian; 13.07.2010
comment
хммм.. Формы в форме курсора всегда отображаются за TMenuItem (для всего остального он отображается нормально). Я уже использовал SetWindowPos и ​​fsStayOnTop. Вы случайно не знаете, как это решить, не так ли? - person Dian; 13.07.2010
comment
Нет, не знаю; Мое предположение: окно меню также помечено как остающееся наверху. Попробуйте отправить своему окну SetWindowPos, посмотрите, сможете ли вы поднять его выше. - person Cosmin Prund; 14.07.2010

Я покажу вам один способ, который отличается от того, что я предлагал вам ранее.
Вы сохраняете свой холст с помощью Canvas.CopyRect на каком-то временном холсте. при первом наведении мыши на холст.
Затем при перемещении мыши сначала скопируйте временный холст на целевой холст, а затем нарисуйте курсор.

person Himadri    schedule 12.07.2010
comment
Я попробовал это решение, но было слишком сложно отслеживать все курсоры мыши и их предыдущие позиции. Но спасибо за ответ, я ценю это. - person Dian; 12.07.2010

Имейте эталонное изображение (именно так должен выглядеть ваш холст без нарисованного на нем курсора мыши), скопируйте его во временное растровое изображение, а затем нарисуйте курсор на этом временном растровом изображении. Наконец, нарисуйте свое изображение на холсте.

Это также позволит вам очень легко создавать более сложные временные наложения: вам просто нужно нарисовать их поверх эталонного растрового изображения в соответствии с их Z-порядком. Поскольку они не касаются фона, вам не нужно беспокоиться об устранении призраков.

person Stephane    schedule 12.07.2010
comment
Будет ли это работать, если фон изменится (сильно)? Фон — это само приложение, поэтому пользователи что-то печатают и делают другие вещи… и он часто меняется, почти так же часто, как двигаются мыши. - person Dian; 12.07.2010
comment
Это то же решение, что я дал. - person Himadri; 12.07.2010