Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Фрейм, PaintBox и клавиатура... [D6, Win2k]


Страницы:   1 2

tunguss ©   (2005-05-20 18:05:00) 

Вот есть вопрос к вам, уважаемые господа.

Описываю ситуацию.

Есть фрейм (он обязателен по умолчанию - без него никуда :) ) - разрабатывается отдельно, но тестируется на форме. Наследник фрейма, естественно.

Я положил в свое время на него PaintBox во всю ширь (это важно) чтобы рисовать по канвасу без каких-либо заморочек (об этой я еще тогда не знал :) ). Возможно именно тогда я ошибся и следовало бы создавать канвас в ран-тайме - сейчас это возможное решение, но, как вы понимаете, не желательное (не то что это трудно переделать, но существует опасность возникновения побочных проблем).

Итак. Проблема жутко тривиальная - фрейму не поймать нажатые клавиши. Все. Причем с мышью все в порядке (она как раз ловится PaintBox'ом).

Форма их принимать не может, потому что тогда проект не будет соответствовать спецификации. Все способы с хуками, переопределениями KeyDown и поимкой messag'ей - перепробованы.

Вполне логично предположить, что PaintBox берет на себя эти самые messag'ы. Но у PaintBox'а нет ивентов-обрабочиков клавиатуры!

Вот так. Прошу высказывать возможные решения проблемы. Поскольку есть вероятность, что для ее решения требуются минимальные усилия, которые либо просто не приходят в голову либо сказывается недостаток опыта :)


tunguss   (2005-05-26 15:31:00) [21]

Всем-всем-всем, кто сюда наткнется. Вероятно обнаружена бага в 6-7 дельфях (насчет других не знаю). Что делаем. Создаем фрейм и биндим ему OnKeyDown. В обработчике пишем что-нибудь вроде 'Key catched'. Кидаем фрейм на палитру и затем на пустую форму (необязательный шаг - можно и в рантайме его...).  Запускаем. Тыркаем буквенные клавиши. Все пойманы - хорошо. Тыкаем какую-нибудь стрелку. Упс - не поймало. Тыкаем буквенные клавиши.... Упс -.... тоже не поймало! А KeyDown должен ловить все!... Вот так. У кого есть доводы против того, что это бага и пути ее решения без правки кода формы (AppEvents ни на фрейме ни на форме тоже нежелателен) - пишите пожалуйста.


tunguss   (2005-05-24 14:09:00) [22]

Да, все приведенные примеры /отдельно/ от программы работают. Но не работают у меня в программе :). Все еще ищу хорошо укрывшуюся багу.


tunguss   (2005-05-24 14:07:00) [23]

Смутило тем, что чтобы фрейм получил фокус нужно тыкнуть в него мышкой :). Это метод когда на форме много контролов - пока так и есть - но в результирующей проге их не будет. Просто смутило. Не возмутило, не разозлило, ни чего еще подобное :)).


jack128   (2005-05-24 00:26:00) [24]

tunguss ©   (23.05.05 12:46) [2]
Немного смутило название процедуры PaintBox1Click, но ради эксперимента попробовал даже с
ней :)

Чем оно тебя смутило?? Автотматом генерируемое название обработчика события OnClick для компонента с именем PaintBox1. С высокой долей вероятности - этот компонент имеет тип TPaintBox. Короче

Unit1

dfm

object Form1: TForm1
 Left = 192
 Top = 107
 Width = 696
 Height = 480
 Caption = 'Form1'
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'MS Sans Serif'
 Font.Style = []
 OldCreateOrder = False
 PixelsPerInch = 96
 TextHeight = 13
 inline Frame21: TFrame2
   Left = 112
   Top = 80
   Width = 320
   Height = 240
   TabOrder = 0
 end
end


pas

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Frame21: TFrame2;
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

end.


Unit2

dfm

object Frame2: TFrame2
 Left = 0
 Top = 0
 Width = 320
 Height = 240
 TabOrder = 0
 object PaintBox1: TPaintBox
   Left = 0
   Top = 0
   Width = 320
   Height = 240
   Align = alClient
   OnClick = PaintBox1Click
 end
end


pas

unit Unit2;

interface

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

type
 TFrame2 = class(TFrame)
   PaintBox1: TPaintBox;
   procedure PaintBox1Click(Sender: TObject);
 private
   procedure FrameKeyPress(Sender: TObject; var Key: Char);
   { Private declarations }
 public
   { Public declarations }
 end;

implementation

{$R *.dfm}

procedure TFrame2.FrameKeyPress(Sender: TObject; var Key: Char);
begin
ShowMessage('Yra');
end;

procedure TFrame2.PaintBox1Click(Sender: TObject);
begin
OnKeyPress := FrameKeyPress;
if CanFocus then
  SetFocus;
end;

end.


tunguss   (2005-05-23 16:43:00) [25]

Попробовал. И так не прошло :(. Спасибо вам ребята за помощь но такое чувство что действительно где-то то ли в моем коде то ли в коде заказчика делается какая-то гадость (нет, в конструкторе формы я оспасных свойств не устанавливаю :)).

На всякий случай уточню, что мне нужен WM_KEYDOWN, поскольку я перехватываю нажатие стрелок - навигация и все такое.


VladimirB   (2005-05-23 16:29:00) [26]

TFrame2 = class(TFrame)
   PaintBox1: TPaintBox;
   procedure PaintBox1Click(Sender: TObject);
 private
   { Private declarations }
   procedure WMCharQ(var Message: TWMChar); message WM_CHAR;
  public
   { Public declarations }
 end;

implementation

{$R *.dfm}

procedure TFrame2.WMCharQ(var Message: TWMChar);
begin
ShowMessage('sdfsd');
end;

procedure TFrame2.PaintBox1Click(Sender: TObject);
begin
SetFocus;
end;

А это форма использующая фрейм.
type
 TForm1 = class(TForm)
   Frame21: TFrame2;
   Memo1: TMemo;
   procedure FormShow(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
Frame21.SetFocus;
end;


tunguss   (2005-05-23 12:46:00) [27]

По поводу наследования абсолютно согласен. Действительно, не логично :). Поторопился :).

Но... Ваш метод к сожалению не работает. Я его уже пробовал раньше (уже не перечислить сколько методов я пробовал :) ), но на всякий случай попробовал еще раз. Немного смутило название процедуры PaintBox1Click, но ради эксперимента попробовал даже с
ней :) (первым дело конечно же поставил это дело в конструктор).

KeyPreview у формы установлен в False, но, собственно, и со значением True фрейм абсолютно также упрямится :). ActiveControl на форме - тот самый фрейм. Но другие компоненты, тем не менее, независимо ни от KeyPreviiew, ни от ActiveControl, реагируют на нажатия клавиш так, как если бы фрейма вообще не было.

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

В любом случае, благодарю вас за внимание к моей проблеме.


jack128   (2005-05-21 17:19:00) [28]

tunguss ©   (20.05.05 18:05)
Вполне логично предположить, что PaintBox берет на себя эти самые messag'ы.

нет, не логично. PaintBox - наследник GraphicControl'а и сообщения от клавы не принемает. А фрейм не принимает на себя обработку начатия клавиш, так как он не имеет фокуса ввода. В отличии от всяких Edit'ов, Memo и тд фрейм при клике по нему не получает фокуса, так что это нужно делать самостоятельно.

type
 TFrame2 = class(TFrame)
   PaintBox1: TPaintBox;
   procedure PaintBox1Click(Sender: TObject);
 private
   procedure FrameKeyPress(Sender: TObject; var Key: Char);
   { Private declarations }
 public
   { Public declarations }
 end;

implementation

{$R *.dfm}

procedure TFrame2.FrameKeyPress(Sender: TObject; var Key: Char);
begin
 ShowMessage('Yra');
end;

procedure TFrame2.PaintBox1Click(Sender: TObject);
begin
 OnKeyPress := FrameKeyPress;
 if CanFocus then
   SetFocus;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо