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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Enabled для biHelp 
V
    Опции темы
NieL
Дата 30.12.2008, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Столкнулся с очередной проблемой. Можно ли выполнить Enabled для biHelp в заголовке окна.
PM MAIL   Вверх
Rrader
  Дата 1.1.2009, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 70
Всего: 191



Запретить нажатие на эту кнопку можно вот таким кодом:
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
  protected
    procedure OnWMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.OnWMNCHitTest(var Msg: TWMNCHitTest);
begin
  inherited;
  if Msg.Result = HTHELP then
    Msg.Result := HTBORDER;
end;

end.

Но кнопка будет выглядеть активной (Hint отсутствует). Стандартных средств для того, чтобы сделать ее неактивной, увы, нет. Но нарисовать все же можно. В Windows есть возможность нарисовать эту кнопку (в Disabled режиме) встроенными средствами при включенных темах, например, таким кодом:
Код

uses UxTheme;
...

procedure TForm1.Button1Click(Sender: TObject);
var
  Theme: HTHEME;
begin
  Theme := OpenThemeData(Handle, 'WINDOW');
  try
    DrawThemeBackground(Theme, Canvas.Handle, WP_HELPBUTTON,
      HBS_DISABLED, Rect(0, 0, 21, 21), NIL);
  finally
    CloseThemeData(Theme);
  end;
end;

Далее следует учесть несколько вещей:
  •  Window Manager (именно он рисует заголовок) недокументирован, и в каждой версии Windows может быть реализован через различные функции по отрисовке (см.ниже);
  •  В Win9x (нет Theme API) и 2000-XP (Vista) при классической теме эффекта Disabled не будет, потому что HBS_DISABLED как таковой смысла иметь не будет;
  •  В Windows XP и Windows Vista заголовок при включенных темах рисуется различными функциями.
Для учебных целей привожу пример для Windows XP, через сплайсинг функции DrawThemeBackground:
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, UxTheme, Themes, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  protected
    procedure OnWMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TFarJmp = packed record
    PuhsOp: Byte;
    PushArg: Pointer;
    RetOp: Byte;
  end;

  TOldCode = packed record
    One: Cardinal;
    Two: Word;
  end;

var
  Form1: TForm1;
  JmpDTB: TFarJmp;
  OldDTB: TOldCode;
  DTBAddr: Pointer = NIL;

implementation

{$R *.dfm}

function TrueDrawThemeBackground(hTheme: HTHEME; hdc: HDC; iPartId,
  iStateId: Integer; const pRect: TRect; pClipRect: PRECT): HRESULT; stdcall;
begin
  WriteProcessMemory(INVALID_HANDLE_VALUE, DTBAddr,
    @OldDTB, SizeOf(TOldCode), PDWORD(NIL)^);
  Result := DrawThemeBackground(hTheme, hdc, iPartId,
    iStateId, pRect, pClipRect);
  WriteProcessMemory(INVALID_HANDLE_VALUE, DTBAddr,
    @JmpDTB, SizeOf(TFarJmp), PDWORD(NIL)^);
end;

function NewDrawThemeBackground(hTheme: HTHEME; hdc: HDC; iPartId,
  iStateId: Integer; const pRect: TRect; pClipRect: PRECT): HRESULT; stdcall;
begin
  if iPartId = WP_HELPBUTTON then 
    iStateId := HBS_DISABLED;
  Result := TrueDrawThemeBackground(hTheme, hdc, iPartId,
    iStateId, pRect, pClipRect);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Module: DWORD;
begin
  BorderStyle := bsDialog;
  BorderIcons := BorderIcons + [biHelp];
  if InitThemeLibrary then
  begin
    Module := GetModuleHandle('uxtheme.dll');
    DTBAddr  := GetProcAddress(Module, 'DrawThemeBackground');
    ReadProcessMemory(INVALID_HANDLE_VALUE, DTBAddr,
      @OldDTB, SizeOf(TOldCode), PDWORD(NIL)^);
    JmpDTB.PuhsOp  := $68;
    JmpDTB.PushArg := @NewDrawThemeBackground;
    JmpDTB.RetOp   := $C3;
    WriteProcessMemory(INVALID_HANDLE_VALUE, DTBAddr, @JmpDTB,
      SizeOf(TFarJmp), PDWORD(NIL)^);
  end;
end;

procedure TForm1.OnWMNCHitTest(var Msg: TWMNCHitTest);
begin
  inherited;
  if Msg.Result = HTHELP then
    Msg.Result := HTBORDER;
end;

end.

В аттаче прикрепил пример

Это сообщение отредактировал(а) Rrader - 1.1.2009, 17:54

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  biHelp__XP_.rar 7,68 Kb


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

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

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

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


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

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


 




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


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

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