Автор: ShIvADeSt
Дата сообщения: 11.10.2008 11:11
Maks150988
Держи код, вроде все отладил, все состояния сделал. Кстати если тебе не нужна функция (у тебя таких несколько, то смысл делать ее функцией - лучше процедурой сделать)
[more]
Код:
program sample;
uses
Windows, Messages, Classes, UxTheme, TmSchema;
{$R dialog.res}
var
BtnRect : TRect; // Координаты для кнопки свертывания
WndRect : TRect; // Координаты главного окна
VisTheme : hTheme; // Хэндл открытой темы оформления
hWndApp : THandle; // Хэндл главного диалога приложения
Pressed : Boolean; // Переменная нажатия рисуемой кнопки
Focused : Boolean; // Переменная сфокусированности кнопки
Actived : Boolean; // Переменная активности главного окна
CursorPt : TPoint; // Координаты курсора в главном окне
IsWinXp : Boolean;
function IsOsWindowsXp : Boolean;
var
osVerInfo : TOSVersionInfo;
majorVer : Integer;
minorVer : Integer;
begin
osVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
if GetVersionEx(osVerInfo) then
begin
majorVer := osVerInfo.dwMajorVersion;
minorVer := osVerInfo.dwMinorVersion;
case osVerInfo.dwPlatformId of
VER_PLATFORM_WIN32_NT :
begin
if (majorVer = 5) and (minorVer = 1) then
Result := TRUE
else
Result := FALSE;
end;
else
Result := FALSE;
end;
end
else
Result := FALSE;
end;
// Функция для прорисовки кнопки светтывания в окне программы
procedure PaintMinimizeToolButton;
var
WinDC : HDC;
SizeX : Integer;
SizeY : Integer;
Xframe : Integer;
Yframe : Integer;
begin
GetWindowRect(hWndApp, WndRect);
WinDC := GetWindowDc(hWndApp);
SizeX := GetSystemMetrics(SM_CXSIZE);
SizeY := GetSystemMetrics(SM_CYSIZE);
xFrame := GetSystemMetrics(SM_CXFRAME);
yFrame := GetSystemMetrics(SM_CYFRAME);
BtnRect := Bounds(WndRect.Right - WndRect.Left - xFrame - SizeX - 6, yFrame + 2, SizeX - 12, SizeY - 12);
// Курсор перемещаем над кнопкой с зажатой левой кнопкой мыши
if (Pressed and Actived and Focused ) then
begin
if IsWinXp = TRUE then
begin
if InitThemeLibrary and UseThemes then
DrawThemeBackground(VisTheme, WinDC, WP_MINBUTTON, MINBS_PUSHED, BtnRect, nil);
end
else
DrawFrameControl(WinDC, BtnRect, DFC_CAPTION, DFCS_CAPTIONMIN or DFCS_PUSHED);
end
else
// рисуем горячую кнопку (при наведении) даже если форма не активна
if (NOT Pressed and Focused) then
begin
if IsWinXp = TRUE then
begin
if InitThemeLibrary and UseThemes then
DrawThemeBackground(VisTheme, WinDC, WP_MINBUTTON, MINBS_HOT, BtnRect, nil);
end
else
DrawFrameControl(WinDC, BtnRect, DFC_CAPTION, DFCS_CAPTIONMIN or DFCS_PUSHED);
end
else
// если форма не активна и мышь не на кнопке рисуем неактивную кнопку
if (NOT Actived and NOT Focused) then
begin
if IsWinXp = TRUE then
begin
if InitThemeLibrary and UseThemes then
DrawThemeBackground(VisTheme, WinDC, WP_MINBUTTON, MINBS_INACTIVE, BtnRect, nil);
end
else
DrawFrameControl(WinDC, BtnRect, DFC_CAPTION, DFCS_CAPTIONMIN or DFCS_PUSHED);
end
else
// Обычное состояние кнопки
if IsWinXp = TRUE then
begin
if InitThemeLibrary and UseThemes then
DrawThemeBackground(VisTheme, WinDC, WP_MINBUTTON, MINBS_NORMAL, BtnRect, nil);
end
else
DrawFrameControl(WinDC, BtnRect, DFC_CAPTION, DFCS_CAPTIONMIN);
ReleaseDC(hWndApp, WinDC);
end;
// Функция для загрузки используемой темы оформления
function OpenShellTheme : Boolean;
begin
// Если ОС опознана, загружаем текущую используемую тему
Result:=False;
if IsWinXp then
begin
// Открываем тему, а также проверяем ее использование
if InitThemeLibrary and UseThemes then
VisTheme := OpenThemeData(hWndApp, 'Window');
Result := TRUE;
end;
end;
// Функция для выгрузки используемой темы оформления
function CloseShellTheme : Boolean;
begin
// Если ОС опознана, загружаем текущую используемую тему
Result:=False;
if IsWinXp then
begin
// Открываем тему, а также проверяем ее использование
if InitThemeLibrary and UseThemes then
CloseThemeData(VisTheme);
Result := TRUE;
end;
end;
function MainDlgProc(hWnd : HWND; uMsg : UINT; wParam : WPARAM; lParam : LPARAM) : BOOL; stdcall;
begin
Result := FALSE;
case uMsg of
// Функция обработки инициализации диалогового окна
WM_INITDIALOG :
begin
hWndApp := hWnd;
// Проверяем версию операционной системы
if IsOsWindowsXp then
IsWinXp := TRUE
else
IsWinXp := FALSE;
// Загружаем текущую тему оформления
OpenShellTheme;
end;
// Функция обработки сообщений на изменение темы оформления
WM_THEMECHANGED :
begin
// Если ОС опознана, выгружаем текущую тему оформления
CloseShellTheme;
// Загружаем текущую тему оформления
OpenShellTheme;
end;
// Функция обработки когда окно видимо на экране
WM_PAINT, WM_NCPAINT, WM_NCACTIVATE :
begin
// Выполняем отрисовку кнопки после выполненных условий
PaintMinimizeToolButton;
end;
// Функция обработки когда окно неактивно
WM_ACTIVATE :
begin
if LoWord(wParam) = WA_INACTIVE then
Actived := FALSE
else
Actived := TRUE;
// Выполняем отрисовку кнопки после выполненных условий
PaintMinimizeToolButton;
end;
// Перемещаем курсор над окном
WM_NCMOUSEMOVE :
begin
GetWindowRect(hWndApp, WndRect);
GetCursorPos(CursorPt);
Dec(CursorPt.X, WndRect.Left);
Dec(CursorPt.Y, WndRect.Top);
// Если курсор заходит в координаты рисуемой кнопки
if PtInRect(BtnRect, CursorPt) then
begin
// Кнопка мыши нажата в данный момент
if HiWord(GetAsyncKeyState(VK_LBUTTON)) <> 0 then
begin
Pressed := TRUE;
Focused := TRUE;
end
// Кнопка мыши не нажата в данный момент
else
begin
Pressed := FALSE;
Focused := TRUE;
end;
end
// Указатель не находится в данный момент на кнопке
else
begin
Pressed := FALSE;
Focused := FALSE;
end;
// Выполняем отрисовку кнопки после выполненных условий
PaintMinimizeToolButton;
end;
// Нажали на кнопку
WM_MOUSEMOVE:
begin
if Focused then begin
Focused:=False;
PaintMinimizeToolButton;
end;
end;
WM_NCLBUTTONDOWN:
begin
if GetCapture<>hWndApp then SetActiveWindow(hWnd); // делаем активным наше приложение
GetWindowRect(hWndApp, WndRect);
GetCursorPos(CursorPt);
Dec(CursorPt.X, WndRect.Left);
Dec(CursorPt.Y, WndRect.Top);
if PtInRect(BtnRect, CursorPt) then //нажали конкретно на кнопку
begin
Pressed := TRUE;
Focused := TRUE;
// Выполняем отрисовку кнопки после выполненных условий
PaintMinimizeToolButton;
Result := TRUE; //это чтобы окно не таскалось за кнопочку
end
end;
// Отжали левую кнопку мыши
WM_NCLBUTTONUP :
begin
GetWindowRect(hWndApp, WndRect);
GetCursorPos(CursorPt);
Dec(CursorPt.X, WndRect.Left);
Dec(CursorPt.Y, WndRect.Top);
if PtInRect(BtnRect, CursorPt) then
begin
Focused:=true;
PaintMinimizeToolButton;
if Pressed then messagebox(hwndapp,'press!','text',mb_ok);
end
else
begin
Focused:=false;
end;
Pressed:=False;
end;
WM_NCRBUTTONDOWN:
begin
GetCursorPos(CursorPt);
GetWindowRect(hWndApp, WndRect);
CursorPt := Point(CursorPt.X - WndRect.Left, CursorPt.Y - WndRect.Top);
if PtInRect(BtnRect, CursorPt) then
Result := TRUE;
end;
WM_SIZE :
begin
RedrawWindow(hWndApp, PRect(0), 0, RDW_INVALIDATE);
end;
WM_DESTROY, WM_CLOSE :
begin
// Если ОС опознана, выгружаем текущую тему оформления
CloseShellTheme;
// Посылаем приложению команду завершения работы
PostQuitMessage(0);
end;
end;
end;
begin
// Загружаем диалоговое окно из ресурсов модуля
DialogBox(hInstance, MAKEINTRESOURCE(101), 0, @MainDlgProc);
end.