Модераторы: Snowy, Alexeis, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рисование поверх других окон, Надо очистить определенную область 
V
    Опции темы
murod
Дата 14.7.2007, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 17.9.2005
Где: Uzbekistan/Tashke nt

Репутация: нет
Всего: 4



Всем Привет! 
Такая вот задача:
Надо сделать програмку типа Paint. Но он будет рисовать на рабочем столе или поверх других окон. 
Сама Программа занимает верхную область рабочего стола. Там будет только панель инструментов(тип линии, цвет заливки, Ластик, квадрат...).
Рисовать получается. Но вот, как очистить определенную область, например маленкий квадрат? Как сделать Ластик как на Paint. Ясно что на Paint нету заднего фона там можно просто очишать белым или рисовать белый квадрат. А как поступить в моем случаи? Ведь у меня задний фон не белый а там стоит рабочий стол. Первое в голову приходит как то обновить маленький регион рабочего стола. Но не получается. Когда обнавляю регион вместо него рисуется белый квадрат. 
Здесь запутался, дальше не идет. Посоветуйте хоть что.

рисую примерно так:
Код

dc:=GetDC(0);
canv:=TCanvas.Create; 
canv.Handle:=dc;
canv.Ellipse(Mouse.CursorPos.X,Mouse.CursorPos.Y,Mouse.CursorPos.X+20,Mouse.CursorPos.Y+20);

стираю так:
Код

var r:Prect;
-------------------------------------------
r.Left:=Mouse.CursorPos.X;
r.Top:=Mouse.CursorPos.Y;
r.Right:=Mouse.CursorPos.X+10;
r.Bottom:=Mouse.CursorPos.Y+10;
  InvalidateRect(dc,r,true);


Заранее всем спасибо.
--------------------
Люди всего мира берегите природу!  
PM MAIL ICQ   Вверх
Alexeis
Дата 14.7.2007, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



  А почему бы не стирать просто рисуя белый квадратик?


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
nmn
Дата 15.7.2007, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 593
Регистрация: 26.11.2005

Репутация: нет
Всего: 1



а как ты собираешься стирать? восстанавливать то что было раньше? тогда можешь сделать себе фотографию экрана и потом из нее восстанавливать "испорченный" участок

Добавлено через 1 минуту и 49 секунд
и еще IvalidateRect необходимо передавать не дескриптор контекста а дескриптор окна
PM Skype   Вверх
murod
Дата 15.7.2007, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 17.9.2005
Где: Uzbekistan/Tashke nt

Репутация: нет
Всего: 4



Alexeis, если буду стирать белым квадратиком то у меня задний фоном является рабочий стол, мне надо очистить только то что нарисовал. И при этом задним фоном должно быть рабочий стол. По проше у меня как бы два слоя. 1-слой это рабочий стол. 2-слой это то что я рисую. Если смогу обновить прямоугольную область экрана то у меня 2-слой отстирается а 1-слой обновится(windows автоматически перерисует прямоугольную область экрана) вот тогда бы получился ластик.


nmn, 
Цитата

а как ты собираешься стирать? восстанавливать то что было раньше? тогда можешь сделать себе фотографию экрана и потом из нее восстанавливать "испорченный" участок

Это для частных случаев может подойдет, когда у меня статический обычны рабочий стол. Если на рабочем столе будет проигрыватся видео файл(Media player) то тогда я не смогу правильно обновить экран.  

Мне просто нужна функция обновления указанной области экрана, типа IvalidateRect().

Цитата

и еще IvalidateRect необходимо передавать не дескриптор контекста а дескриптор окна

это действительно может помочь. я не правильно обновлял. Попробую IvalidateRect() передать  хендл окна под указателем мышки а не контекст устройства.  
--------------------
Люди всего мира берегите природу!  
PM MAIL ICQ   Вверх
murod
Дата 15.7.2007, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 17.9.2005
Где: Uzbekistan/Tashke nt

Репутация: нет
Всего: 4



нет неработает, не обновляется.
Я поставил ловушку на мыш. обрабатываю события мыши и поним рисую, стираю.
вот код ловушки и как стираю. 
Код

function MouseProc(nCode: Integer; wParam, lParam: Longint): Longint; stdcall;
var dc:THandle;r:Prect;
begin
 dc:=GetDC(0);
r.Left:=Mouse.CursorPos.X;
r.Top:=Mouse.CursorPos.Y;
r.Right:=Mouse.CursorPos.X+10;
r.Bottom:=Mouse.CursorPos.Y+10;
 InvalidateRect(WindowFromPoint(Mouse.CursorPos),r,true);
 result := CallNextHookEx(ourHook, nCode, wParam, lParam);
end;

Посмотрите может еще где делаю не правильно,

Это сообщение отредактировал(а) murod - 15.7.2007, 20:20
--------------------
Люди всего мира берегите природу!  
PM MAIL ICQ   Вверх
nmn
Дата 17.7.2007, 03:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 593
Регистрация: 26.11.2005

Репутация: нет
Всего: 1



вроде InvalidateRect не вызывает перерисовки, а только при добавляет  к перерисовываемой области прямоугольник

Добавлено через 5 минут и 14 секунд
а если окно не перекрывается другими окнами и не выходит за пределы экрана то и сообщение WM_PAINT не присылается, отсюда вывод - шли сам или вызывай UpdateWindow. Может проще сделать фотографию и рисовать на ней?
PM Skype   Вверх
bems
Дата 17.7.2007, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 1
Всего: 88



попробуй рисовать на прозрачном слоистом окне во весь экран


--------------------
Обижено школьников: 8
PM MAIL   Вверх
murod
Дата 17.7.2007, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 17.9.2005
Где: Uzbekistan/Tashke nt

Репутация: нет
Всего: 4



bems, можно подробней ? если не трудно, приведи маленький пример.
--------------------
Люди всего мира берегите природу!  
PM MAIL ICQ   Вверх
bems
Дата 18.7.2007, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 1
Всего: 88



вот примерчик
Код

program DesktopPaint;

uses
  windows,messages;

const sWndClassName='TransparentDrawingSurface';
      sWndName='DesktopPaint';
      TransparentColor=$00010101;
      PictureColor=$0000FF00;
      WH_MOUSE_LL=14;

type MSLLHOOKSTRUCT=record
                    pt:TPoint;
                    mouseData,
                    flags,
                    time:DWORD;
                    dwExtraInfo:pointer;
                    end;

var hHook:THANDLE;SurfaseWnd:HWND;

procedure Paint(wnd:HWND;color:COLORREF;pt:TSmallPoint);
var dc:HDC;OriginalPen:HPEN;OriginalBrush:HBRUSH;
begin
dc:=GetDC(wnd);
OriginalPen:=SelectObject(dc,GetStockObject(NULL_PEN));
OriginalBrush:=SelectObject(dc,CreateSolidBrush(color));
ellipse(dc,pt.x-10,pt.y-10,pt.x+10,pt.y+10);
SelectObject(dc,OriginalPen);
DeleteObject(SelectObject(dc,OriginalBrush));
ReleaseDC(wnd,dc);
end;

function MouseHook(nCode:integer;msg:cardinal;var info:MSLLHOOKSTRUCT):integer;stdcall;
var buttons:integer;pt:TSmallPoint;
begin
result:=CallNextHookEx(0,nCode,integer(msg),integer(@info));
if nCode=HC_ACTION
   then begin
        buttons:=0;
        if Hi(GetAsyncKeyState(VK_LBUTTON))<>0
           then buttons:=MK_LBUTTON;
        if Hi(GetAsyncKeyState(VK_RBUTTON))<>0
           then buttons:=buttons or MK_RBUTTON;
        pt.x:=info.pt.X;
        pt.y:=info.pt.Y;
        SendMessage(SurfaseWnd,WM_MOUSEMOVE,buttons,integer(pt));
        end;
end;

procedure Hook;
begin
hHook:=SetWindowsHookEx(WH_MOUSE_LL,@MouseHook,hInstance,0);
end;

procedure Unhook;
begin
UnhookWindowsHookEx(hHook);
end;

function WndProc(wnd:HWND;msg:cardinal;wParam,lParam:integer):integer;stdcall;
begin
result:=DefWindowProc(wnd,msg,wParam,lParam);
case msg of
  WM_NCCREATE:begin
              SurfaseWnd:=wnd;
              SetLayeredWindowAttributes(wnd,TransparentColor,0,LWA_COLORKEY);
              Hook;
              end;
 WM_NCDESTROY:begin
              Unhook;
              PostQuitMessage(0);
              end;
 WM_MOUSEMOVE:if (wParam and MK_LBUTTON)=0
                 then if (wParam and MK_RBUTTON)<>0
                         then Paint(wnd,TransparentColor,TSmallPoint(lParam))
                         else 
                 else Paint(wnd,PictureColor,TSmallPoint(lParam));
end;
end;

function CreateSurfaceWnd:boolean;
var cls:WNDCLASS;
begin
ZeroMemory(@cls,SizeOf(cls));
with cls do begin
            lpfnWndProc:=@WndProc;
            lpszClassName:=sWndClassName;
            hbrBackground:=CreateSolidBrush(TransparentColor);
            hCursor:=LoadCursor(0,IDC_ARROW);
            end;
result:=(RegisterClass(cls)<>0) and
        (CreateWindowEx(WS_EX_LAYERED or WS_EX_TOPMOST,
                        sWndClassName,sWndName,
                        WS_POPUP or WS_MAXIMIZE or WS_VISIBLE,
                        0,0,0,0,0,0,0,nil)<>0)
end;

var msg:TMSG;
begin
if CreateSurfaceWnd
  then while GetMessage(msg,0,0,0) do
        DispatchMessage(msg);
end.
Левая кнопка мышки рисует, правая стирает

Добавлено через 4 минуты и 2 секунды
недостатки:
- окно иногда "проваливается" под панель задач (но в большей части экрана все в порядке)
- рисовать можно не всеми цветами (т. к. один зарезервирован под прозрачность)


--------------------
Обижено школьников: 8
PM MAIL   Вверх
murod
Дата 19.7.2007, 06:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 113
Регистрация: 17.9.2005
Где: Uzbekistan/Tashke nt

Репутация: нет
Всего: 4



bems, Спасибо большое. Так и буду делать. Только как то мне надо будет чтобы этот окно стояла поверх Панели задач, что бы не проваливался. Этим думаю можно разобратся.
--------------------
Люди всего мира берегите природу!  
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.0533 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.