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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 05.03.2016, 17:47   #1
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
По умолчанию Форма прозрачная для кликов

Здравствуйте, есть такая программа StreamChat для стримеров, она создает полупрозрачное окошко и в нём виден чат, и клики проходят сквозь окно, и любые действия. Если зажать ctrl + shift и мышкой кликнуть в окно то можно его перемещать и тд. Как реализовать такое? Исходник есть но он на питоне, интересует вариант делфи. Находил пример с добавлением параметра в CreateParams но не пойму как изменить этот параметр на лету, т.е. убрать его с формы чтоб она на время стала кликабельной. Хочу сделать вроде что то окошка для заметок, считаю что очень удобным будет
сорц - https://sourceforge.net/projects/streamchat/

Код:
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams (Params);
  Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
end;
после этого сообщения не перехватываются и отлавливать через getasynckeystate думаю - нелепо. Интересует правильный подход в таком случае.
Здравствуйте
NEoMASTERR вне форума Ответить с цитированием
Старый 05.03.2016, 19:49   #2
Iron Monk
Форумчанин
 
Аватар для Iron Monk
 
Регистрация: 05.10.2007
Сообщений: 478
По умолчанию

В CreateForm:
Код:
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TRANSPARENT );
Iron Monk вне форума Ответить с цитированием
Старый 05.03.2016, 23:17   #3
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
По умолчанию

Большое спасибо)
Здравствуйте
NEoMASTERR вне форума Ответить с цитированием
Старый 06.03.2016, 06:18   #4
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Код:
unit Unit1;

interface

uses
  // стандартные модули

const
  WH_KEYBOARD_LL = 13;
  LLKHF_UP = $80;

type
  PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
  KBDLLHOOKSTRUCT = record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: Int64;
  end;

  TKbdHandler = procedure(P: PKBDLLHOOKSTRUCT) of object;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FTransparentClicks: Boolean;
    procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
    procedure HookHandler(P: PKBDLLHOOKSTRUCT);
    procedure StartHook(AHandler: TKbdHandler);
    procedure StopHook;
    procedure SetTransparent;
    procedure SetTransparentClicks(const Value: Boolean);
  public
    property TranparentClicks: Boolean read FTransparentClicks write SetTransparentClicks;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  Hook: HHOOK = 0;
  Handler: TKbdHandler = nil;

function LowLevelKeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if nCode >= 0 then
  begin
    if Assigned(Handler) then
      Handler(Pointer(lParam));
  end;
  Result := CallNextHookEx(Hook, nCode, wParam, lParam);
end;

procedure TForm1.SetTransparentClicks(const Value: Boolean);
begin
  if FTransparentClicks <> Value then
  begin
    FTransparentClicks := Value;
    SetTransparent;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AlphaBlendValue := 100;
  Color := clHighlight;
  BorderStyle := bsNone;
  FormStyle := fsStayOnTop;
  TranparentClicks := True;
  StartHook(HookHandler);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  StopHook;
end;

procedure TForm1.StartHook(AHandler: TKbdHandler);
begin
  Handler := AHandler;
  Hook := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, 0, 0);
end;

procedure TForm1.StopHook;
begin
  if Hook <> 0 then
    UnhookWindowsHookEx(Hook);
end;

procedure TForm1.HookHandler(P: PKBDLLHOOKSTRUCT);
begin
  if P^.vkCode = VK_LCONTROL then
    TranparentClicks := (P^.flags and LLKHF_UP) = LLKHF_UP;
end;

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
  inherited;
  if Msg.Result = htClient then
    Msg.Result := htCaption;
end;

procedure TForm1.SetTransparent;
var
  AStyle: Integer;
begin
  AStyle := GetWindowLong(Handle, GWL_EXSTYLE);
  case FTransparentClicks of
    True:  AStyle := AStyle or WS_EX_TRANSPARENT;
    False: AStyle := AStyle and not WS_EX_TRANSPARENT;
  end;
  SetWindowLong(Handle, GWL_EXSTYLE, AStyle);
  AlphaBlend := FTransparentClicks;
end;

end.
Filka вне форума Ответить с цитированием
Старый 06.03.2016, 12:44   #5
Iron Monk
Форумчанин
 
Аватар для Iron Monk
 
Регистрация: 05.10.2007
Сообщений: 478
По умолчанию

Цитата:
Сообщение от Filka Посмотреть сообщение
Код:
unit Unit1;
Чота не помогло...
Я не про таскание за кузов. Я про клик насквозь)))
Iron Monk вне форума Ответить с цитированием
Старый 06.03.2016, 13:44   #6
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

Цитата:
Сообщение от Iron Monk Посмотреть сообщение
Чота не помогло...
Я не про таскание за кузов. Я про клик насквозь)))
В смысле не помогло? Весь код добавляется в модуль главной формы (Form1), потом нажимаем и держим левый Ctrl...
Filka вне форума Ответить с цитированием
Старый 06.03.2016, 13:49   #7
Iron Monk
Форумчанин
 
Аватар для Iron Monk
 
Регистрация: 05.10.2007
Сообщений: 478
По умолчанию

Цитата:
Сообщение от Filka Посмотреть сообщение
В смысле не помогло? Весь код добавляется в модуль главной формы (Form1), потом нажимаем и держим левый Ctrl...
Пардонирую, всё работает)))
Iron Monk вне форума Ответить с цитированием
Старый 06.03.2016, 14:03   #8
Filka
Форумчанин
 
Регистрация: 29.10.2015
Сообщений: 273
По умолчанию

С помощью CreateParams:
Код:
unit Unit1;

interface

uses
  // стандартные модули

const
  WH_KEYBOARD_LL = 13;
  LLKHF_UP = $80;

type
  PKBDLLHOOKSTRUCT = ^KBDLLHOOKSTRUCT;
  KBDLLHOOKSTRUCT = record
    vkCode: DWORD;
    scanCode: DWORD;
    flags: DWORD;
    time: DWORD;
    dwExtraInfo: Int64;
  end;

  TKbdHandler = procedure(P: PKBDLLHOOKSTRUCT) of object;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FTransparentClicks: Boolean;
    procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
    procedure HookHandler(P: PKBDLLHOOKSTRUCT);
    procedure StartHook(AHandler: TKbdHandler);
    procedure StopHook;
    procedure SetTransparentClicks(const Value: Boolean);
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  public
    property TransparentClicks: Boolean read FTransparentClicks write SetTransparentClicks;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

var
  Hook: HHOOK = 0;
  Handler: TKbdHandler = nil;

function LowLevelKeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if nCode >= 0 then
  begin
    if Assigned(Handler) then
      Handler(Pointer(lParam));
  end;
  Result := CallNextHookEx(Hook, nCode, wParam, lParam);
end;


procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
  begin
    case FTransparentClicks of
      True:  ExStyle := ExStyle or WS_EX_TRANSPARENT;
      False: ExStyle := ExStyle and not WS_EX_TRANSPARENT;
    end;
  end;
  AlphaBlend := FTransparentClicks;
end;

procedure TForm1.SetTransparentClicks(const Value: Boolean);
begin
  if FTransparentClicks <> Value then
  begin
    FTransparentClicks := Value;
    RecreateWnd;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  AlphaBlendValue := 100;
  Color := clHighlight;
  BorderStyle := bsNone;
  FormStyle := fsStayOnTop;
  TransparentClicks := True;
  StartHook(HookHandler);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  StopHook;
end;

procedure TForm1.StartHook(AHandler: TKbdHandler);
begin
  Handler := AHandler;
  Hook := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, 0, 0);
end;

procedure TForm1.StopHook;
begin
  if Hook <> 0 then
    UnhookWindowsHookEx(Hook);
end;

procedure TForm1.HookHandler(P: PKBDLLHOOKSTRUCT);
begin
  if P^.vkCode = VK_LCONTROL then
    TransparentClicks := (P^.flags and LLKHF_UP) = LLKHF_UP;
end;

procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
  inherited;
  if Msg.Result = htClient then
    Msg.Result := htCaption;
end;

end.

Последний раз редактировалось Filka; 07.03.2016 в 08:56.
Filka вне форума Ответить с цитированием
Старый 07.03.2016, 11:18   #9
NEoMASTERR
Форумчанин
 
Аватар для NEoMASTERR
 
Регистрация: 22.12.2010
Сообщений: 175
По умолчанию

Как сделать под Ctrl+Shift ?)
Здравствуйте
NEoMASTERR вне форума Ответить с цитированием
Старый 07.03.2016, 12:05   #10
Iron Monk
Форумчанин
 
Аватар для Iron Monk
 
Регистрация: 05.10.2007
Сообщений: 478
По умолчанию

Цитата:
Сообщение от NEoMASTERR Посмотреть сообщение
Как сделать под Ctrl+Shift ?)
Код:
if P^.vkCode = VK_LCONTROL + VK_LSHIFT then
Iron Monk вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
прозрачная форма, как в windows 7 lezgin Общие вопросы Delphi 10 20.11.2013 10:32
прозрачная форма ivan12 C++ Builder 1 08.08.2012 23:00
Прозрачная форма Хамяг Мультимедиа в Delphi 12 08.01.2009 09:27
Отправка\Приём сообщения. Прозрачная форма. Zeraim Общие вопросы Delphi 6 26.12.2008 20:02