Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.07.2011, 13:05   #1
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию Рисование на рабочем столе...

Здраствуйте, уважаемые!
Подскажите, можно ли нарисовать что-то на рабочем столе?
Причем, без ручной перерисовки всего стола.
Скажем, нарисовать линию произвольную.
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Старый 12.07.2011, 13:12   #2
MadReason
Ищу работу
Форумчанин
 
Аватар для MadReason
 
Регистрация: 16.02.2007
Сообщений: 269
По умолчанию

http://programmersforum.ru/showthread.php?t=50965
Пишу на Delphi все что угодно, недорого, красиво, с комментариями
###icq 107335###
MadReason вне форума Ответить с цитированием
Старый 12.07.2011, 13:13   #3
psycho-coder
Участник клуба
 
Аватар для psycho-coder
 
Регистрация: 06.04.2009
Сообщений: 1,524
По умолчанию

неактуально
psycho-coder вне форума Ответить с цитированием
Старый 12.07.2011, 13:20   #4
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

GetDC(0) не катит - так можно нарисовать непосредственно на экране.
Мне нужно именно на рабочем столе (ниже любого окна, в том числе и иконок)

Брать обоину, дорисовывать к ней изображение и обновлять картинку- совершенно не вариант.

Есть несколько способов сделать форму поверх всех окон. А есть ли способ сделать окно ниже всех окон?..
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}

Последний раз редактировалось Johnson; 12.07.2011 в 13:28.
Johnson вне форума Ответить с цитированием
Старый 12.07.2011, 14:11   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

попробуйте через SetWindowPos
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 12.07.2011 в 14:46.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.07.2011, 21:41   #6
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Вот есть упрощённый вариант, не обрабатывает изменение размера рабочего стола и т. п. Наверное, нужны админские права, отключенный антивирус и версия винды не любая. Но тут основная цель была не рисовать на рабочем столе, а заинжектиться в explorer.
exe
Код:
uses
  Windows;

var
  hWindow: HWND;
  hProcess, hThread: THandle;
  processId, threadId: Cardinal;
  pFileName: PChar;
  n: Cardinal;
  pLoadLibrary, pFreeLibrary: Pointer;
  hKernel32, hDrawerDll: HMODULE;
  fileName: array [0..MAX_PATH] of Char;

begin
  SearchPath(nil, 'drawer.dll', nil, sizeof(fileName), @fileName, PPChar(nil)^);
  hWindow := FindWindow('ProgMan', nil);
  GetWindowThreadProcessId(hWindow, processId);
  hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, processId);
  pFileName := VirtualAllocEx(hProcess, nil, sizeof(fileName),
    MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
  WriteProcessMemory(hProcess, pFileName, @fileName, sizeof(fileName), n);
  hKernel32 := GetModuleHandle('kernel32.dll');
  pLoadLibrary := GetProcAddress(hKernel32, 'LoadLibraryA');
  pFreeLibrary := GetProcAddress(hKernel32, 'FreeLibrary');
  hThread := CreateRemoteThread(hProcess, nil, 0, pLoadLibrary,
    pFileName, 0, threadId);
  WaitForSingleObject(hThread, INFINITE);
  GetExitCodeThread(hThread, hDrawerDll);
  CloseHandle(hThread);
  VirtualFreeEx(hProcess, pFileName, 0, MEM_RELEASE);
  MessageBox(0, 'Press OK to unload', '...', 0);
  hThread := CreateRemoteThread(hProcess, nil, 0, pFreeLibrary,
    Pointer(hDrawerDll), 0, threadId);

  WaitForSingleObject(hThread, INFINITE);
  GetExitCodeThread(hThread, hDrawerDll);

  CloseHandle(hThread);
  CloseHandle(hProcess);
end.
dll
Код:
library Drawer;

uses
  Windows, Messages;

var
  hWindow: HWND;
  processId: DWORD;
  hWndDc, hBitmapDc: HDC;
  hBitmap: HGDIOBJ;
  hPen, hBrush1, hBrush2: HGDIOBJ;
  wndRect: TRect;
  wndWidth, wndHeight, wndCX, wndCY, size: LongInt;
  prevWindowProc: Pointer;

function WindowProc(hWnd: HWND; Msg: UINT; wParam: WPARAM;
  lParam: LPARAM): LRESULT; stdcall;
var
  hOldBrush: HGDIOBJ;
begin
  Result := 0;
  case Msg of
    WM_ERASEBKGND:
    begin
      CallWindowProc(prevWindowProc, hWnd, Msg, wParam, lParam);
      BitBlt(wParam, 0, 0, wndWidth - 1, wndHeight - 1, hBitmapDc, 0, 0, SRCAND);
      Result := 1;
    end;
    else
      Result := CallWindowProc(prevWindowProc, hWnd, Msg, wParam, lParam);
  end;
end;

procedure DllEntryPoint(Reason: Integer);
var
  ProcessId: Cardinal;
begin
  GetWindowThreadProcessID(hWindow, ProcessId);
  if ProcessID <> GetCurrentProcessID() then
    exit;
  if Reason = DLL_PROCESS_DETACH then
  begin
    SetWindowLong(hWindow, GWL_WNDPROC, Integer(prevWindowProc));

    DeleteDc(hBitmapDc);
    DeleteObject(hBitmap);
    DeleteObject(hPen);
    DeleteObject(hBrush1);
    DeleteObject(hBrush2);
  end;
end;

begin
  DisableThreadLibraryCalls(hInstance);

  hWindow := FindWindow('Progman', nil);
  hWindow := GetWindow(hWindow, GW_CHILD);

  GetWindowThreadProcessID(hWindow, ProcessId);
  if ProcessID <> GetCurrentProcessID() then
    exit;

  GetWindowRect(hWindow, wndRect);
  wndWidth := wndRect.Right - wndRect.Left + 1;
  wndHeight := wndRect.Bottom - wndRect.Top + 1;
  wndCX := wndWidth div 2;
  wndCY := wndHeight div 2;
  if wndWidth > wndHeight then
    size := wndHeight div 4
  else
    size := wndWidth div 4;

  hWndDc := GetDC(hWindow);
  hBitmap := CreateCompatibleBitmap(hWndDc, wndWidth, wndHeight);
  hBitmapDc := CreateCompatibleDC(hWndDc);
  ReleaseDc(hWindow, hWndDc);
  hPen := GetStockObject(BLACK_PEN);
  hBrush1 := CreateHatchBrush(HS_CROSS, RGB(0, 0, 0));
  hBrush2 := GetStockObject(WHITE_BRUSH);

  SelectObject(hBitmapDc, hBitmap);
  SelectObject(hBitmapDc, hPen);
  SelectObject(hBitmapDc, hBrush1);
  PatBlt(hBitmapDc, 0, 0, wndWidth - 1, wndHeight - 1, PATCOPY);
  SelectObject(hBitmapDc, hBrush2);
  Ellipse(hBitmapDc, wndCX - size, wndCY - size, wndCX + size, wndCY + size);

  prevWindowProc := Pointer(
    SetWindowLong(hWindow, GWL_WNDPROC, Integer(@WindowProc))
    );

  DllProc := DllEntryPoint;
end.
Somebody вне форума Ответить с цитированием
Старый 13.07.2011, 02:13   #7
Олвин
Экспериментатор
Форумчанин
 
Аватар для Олвин
 
Регистрация: 16.04.2008
Сообщений: 218
По умолчанию

Цитата:
А есть ли способ сделать окно ниже всех окон?..
Это не лучший способ, но всё же
Код:
ParentWindow := FindWindow('ProgMan', nil);
где FindWindow('ProgMan', nil) - получение хендла раб. стола в ХР.
Для создания сложных вещей не нужны сложные интерфейсы. (с) Линус Торвальдс
Олвин вне форума Ответить с цитированием
Старый 13.07.2011, 19:22   #8
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

Цитата:
Вот есть упрощённый вариант, не обрабатывает изменение размера рабочего стола и т. п. Наверное, нужны админские права, отключенный антивирус и версия винды не любая. Но тут основная цель была не рисовать на рабочем столе, а заинжектиться в explorer.
Вот за это чудо спасибо большое! Буду курить код. Насчет антивиря - не страшно, есть методы обхода паники...

Цитата:
Это не лучший способ, но всё же
Я об этом подумывал... Но вчера меня что-то от этого оттолкнуло...
Случайно, прогман не поверх обоев ли отрисовывается? Насколько я понимаю, прогман - прозрачное приложение, на котором отрисовываются и обрабатываются значки... Было бы не плохо ниже него залезть.
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Рисование текста на рабочем столе artemavd Общие вопросы Delphi 9 23.10.2010 06:08
ЧАТ на Рабочем столе! Kachimov Свободное общение 7 11.08.2010 01:21
Анимация на рабочем столе Djonik Помощь студентам 2 09.12.2009 19:58
кнопка на рабочем столе guffer Общие вопросы Delphi 3 08.07.2009 12:15
Значки на рабочем столе Xardas Свободное общение 4 01.03.2008 20:21