Суббота, 27.04.2024, 05:47
Приветствую Вас Гость

Не ошибается тот, кто ничего не делает.
Но и ничего не делать - ошибка.

Эмиль Кроткий

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Delphi » Разное » Управление окном с клавиатуры (как лучше сделать?)
Управление окном с клавиатуры
BLACK_CRAFTER666Дата: Пятница, 19.07.2013, 12:50 | Сообщение # 1
Сержант
Группа: Пользователи
Сообщений: 31
Репутация: 0
Статус: Offline
Здравствуйте.
Нужно сделать настройку клавиш для управления своим окном (типа как в играх).
Сделал ListView, в котором ловлю сообщение WM_KEYDOWN и получаю код нажатой клавиши.
http://i47.fastpic.ru/big/2013/0719/42/84f92301526f1ec8b79da42c0cc96942.jpg (почему-то тэги запрещены)
Далее, код клавиши нужно присвоить некой переменной, чтобы потом отловить в WM_KEYDOWN главного окна.
Примерно так:

Код
WM_KEYDOWN:
    if wparam = <переменная к кодом клавиши> then
// действие

Но проблема в том, как в список клавиш добавить еще и модификатор (ctrl,alt,shift)?
Конечно, можно их checkbox'ами оформить и if'ами прописать, но это же такая куча нелепой писанины!
Должен же быть более рациональный способ?
Например, можно как-то по-хитрому использовать HotKey не для глобальных горячих клавиш, а только для моего окна? Если да, то как?
Другими словами, мне нужно следующее:
1) Нажимаю в своем окне клавишу J и срабатывает действие 1. Нажимаю Ctrl+J - срабатывает действие 2.
2) Сделать возможным переназначать эти клавиши и сохранить/загрузить их в/из ini-файл/реестр.
Как это проще реализовать на WinAPI + Delphi 7?
p.s. С ini-файлами и реестром работать умею.
p.p.s. Пока это писал, подумал, что, по-видимому, нужно делать это с использованием HotKey. Ведь он просто хранит в себе комбинацию, а не регистрирует горячую клавишу. Как заставить окно реагировать на комбинацию, сохраненную в HotKey'е? Но, опять же, может ли HotKey хранить клавишу без модификаторов?
p.p.p.s. Кажется, опять нагородил smile


Сообщение отредактировал BLACK_CRAFTER666 - Пятница, 19.07.2013, 12:52
 
xaramamburuДата: Суббота, 20.07.2013, 19:35 | Сообщение # 2
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
Цитата
Нужно сделать настройку клавиш для управления своим окном (типа как в играх).
А как в играх?

Цитата
(почему-то тэги запрещены)

Не знаю. Попробуйте использовать в место кодов клавиш их константы VK_LEFT и VK_RIGHT и т.д. список можно найти в интернете.

Цитата
Например, можно как-то по-хитрому использовать HotKey не для глобальных горячих клавиш, а только для моего окна? Если
да, то как? Другими словами, мне нужно следующее: 1) Нажимаю в своем
окне клавишу J и срабатывает действие 1. Нажимаю Ctrl+J - срабатывает
действие 2.
А почему не хотите использовать собственные события окна OnKeyPress или OnKeyDown? Вот посмотрите здесь http://delphiworld.narod.ru/base/symphony_on_keyboard.html . А здесь пример с горячими клавишами http://basicsprog.ucoz.ru/forum/4-13-1 правда обычный без модификаторов (ctrl,alt,shift).

Цитата
Но, опять же, может ли HotKey хранить клавишу без модификаторов?
Не знаю, я с этим особо не работал.))))
 
xaramamburuДата: Суббота, 20.07.2013, 22:08 | Сообщение # 3
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
Да, можно еще использовать функцию GetKeyState (Определяет, каково состояние виртуальной клавиши: поднята, нажата или переключается.).

Вот небольшой пример, при нажатии клавиш 'A', 'W', 'S', 'D' в Label1 выводится сообщение 'Привет', а если нажата клавиша ctrl + 'A', ctrl + 'W', ctrl + 'S', ctrl + 'D' выводится сообщение 'Пока'.
Код
unit Unit1;

interface

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

type
           TForm1 = class(TForm)
             Label1: TLabel;
             procedure FormActivate(Sender: TObject);
           private
             { Private declarations }
            //описание процедуры обработчика сообщений
             procedure ProcessFormMessages(var Msg: tMsg;  var Handled: Boolean);
           public
             { Public declarations }
           end;

var
           Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ProcessFormMessages(var Msg: tMsg;
          var Handled: Boolean);
begin
          { проверка наличия системного сообщения KeyDown }
          case Msg.Message of
           WM_KEYDOWN: if Msg.wParam in [$41, $57, $53, $44] then
           begin
           {Проверяем нажатие клавиши ctrl (если не нажата)}
           if GetKeyState(VK_CONTROL) and $80 = 0 then  
           label1.Caption:='Привет'
           else
           label1.Caption:='Пока';
            { сообщаем о том, что сообщение обработано }
           Handled := True;
           end;
          end;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
             { Делаем ссылку на нового обработчика сообщений }
          Application.OnMessage := ProcessFormMessages;
end;

end.
а так:
if (GetKeyState(VK_CONTROL) and GetKeyState(VK_SHIFT)) and $80 <> 0 then
будет задействованы клавиши CONTROL + SHIFT.

Возможен еще и такой, более простой вариант (комбинация ctrl+ 'V') без задействования обработчика системных сообщений ProcessFormMessages:
Код
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;  Shift: TShiftState);
begin
if (GetKeyState(VK_CONTROL) < 0) and (GetKeyState(Ord('V')) < 0)  then    ShowMessage('Привет');
end;

Смотрите в интернете аналогичных примеров много.:)
 
BLACK_CRAFTER666Дата: Воскресенье, 21.07.2013, 10:26 | Сообщение # 4
Сержант
Группа: Пользователи
Сообщений: 31
Репутация: 0
Статус: Offline
cпасибо. Но это немного не то. Я слишком расплывчато описал суть вопроса.
Цитата (xaramamburu)
А почему не хотите использовать собственные события окна OnKeyPress или OnKeyDown?

Потому, что я пишу на WinAPI без формы. Мне так, почему-то, удобнее, чем с формой) Да и проги работают быстрее и весят меньше)
Еще раз опишу суть:
Основная проблема не в том, чтобы перехватить нажатие именно комбинации клавиш с модификаторами. Меня на другом форуме уже научили, что при нажатии/отпусканию модификатора можно ставить/снимать флаг (boolean). Да и GetKeyState лишним не будет smile
Проблема в том, как запомнить комбинацию с модификатором в ListView и как считать этот модификатор при нажатии?
Если не использовать модификатор, то это делается элементарно. Я уже сделал пример и он работает. Если хотите - выложу код. Там ничего сложного. Однако, о чем идет речь - я не знаю, как таким способом изменять и запоминать модификатор.
Что-то похожее сделано в плеере Light Alloy в настройках клавиатуры (ссылка на скриншот в первом посте). Но как это сделано? Вот вопрос.
p.s. Что значит and $80 = 0? Что за проверка?
 
xaramamburuДата: Воскресенье, 21.07.2013, 20:06 | Сообщение # 5
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
Цитата
я пишу на WinAPI без формы.
И охота вам так издеваться. Я как то пробовал, но у меня терпения не хватило.
Ну и я кажется понял ваш вопрос. Вы хотите, чтоб пользователь мог сам назначать комбинацию клавиш так? И вы хотите определить какую комбинацию он нажал, запомнить ее и в дальнейшем сохранить в INI файле или где то еще так? Как я понял саму клавишу вы определять научились. Осталось понять нажат ли какой либо модификатор (ctrl,alt,shift). Думаю здесь можно поступить также как у меня в примере:

WM_KEYDOWN: if Msg.wParam in [перечисляем список разрешенных клавиш] then
begin
запоминаем код нажатой клавиши в переменную;
{Проверяем нажатие клавиши ctrl }
if GetKeyState(VK_CONTROL) and $80 <> 0 then  запоминаем модификатор  VK_CONTROL или его код в переменную;
{Проверяем нажатие клавиши shift }
if GetKeyState(VK_SHIFT) and $80 <> 0 then запоминаем модификатор VK_SHIFT или его код в
переменную;
{Проверяем нажатие клавиши alt }
if GetKeyState(VK_MENU) and $80 <> 0 then запоминаем модификатор  VK_MENU или его код в
переменную;
{ сообщаем о том, что сообщение обработано }
Handled := True;


В место переменной наверное можно выгрузить в ListView.

Процедура проверки абсолютна аналогична:

WM_KEYDOWN: if Msg.wParam in [перечисляем список разрешенных клавиш] then
begin
запоминаем код нажатой клавиши в переменную;
{Проверяем нажатие клавиши ctrl }
if GetKeyState(VK_CONTROL) and $80 <> 0 then  запоминаем модификатор  VK_CONTROL или его код в переменную;
{Проверяем нажатие клавиши shift }
if GetKeyState(VK_SHIFT) and $80 <> 0 then
запоминаем модификатор VK_SHIFT или его код в
переменную;
{Проверяем нажатие клавиши alt }
if GetKeyState(VK_MENU) and $80 <> 0 then запоминаем модификатор  VK_MENU или его код в
переменную;

{ сообщаем о том, что сообщение обработано }
Handled := True;


по коду клавиши и модификатора определяем действие из ListView;

case действие of

действие1:

действие2:

действие3:
------------
end;


Я думаю как то так, возможно и не прав.)))

Цитата
Меня на другом форуме уже научили, что при нажатии/отпусканию модификатора можно ставить/снимать флаг (boolean).

Если не сложно выложите ссылку на форум.

Цитата
Если хотите - выложу код.

Неплохо было бы посмотреть, а то так сложно о чем то говорить.

Цитата
Что значит and $80 = 0? Что за проверка?

Скорее не так, а вот так GetKeyState(VK_CONTROL) and $80, а затем это сравнивается с 0.
Из справки:
Функция
GetKeyState

Описание:
function GetKeyState(VirtKey: Integer): Integer;
Определяет, каково состояние виртуальной клавиши: поднята, нажата или переключается.

Параметры:
VirtKey: Виртуальная клавиша.

Возвращаемое значение:
Клавиша нажата, если старший бит равен 1, и клавиша переключается, если младший бит равен 1.

$80 - в двоичной системе 10000000 (если я не ошибаюсь), т.е. происходит проверка установлен ли старший бит. Можно проверять и так:
if HiWord(GetKeyState(VK_CONTROL))  <> 0 then
или
if GetKeyState(VK_CONTROL) < 0 then (1 в старшем разряде это признак отрицательного числа (снова если я не ошибаюсь)).
smile
 
BLACK_CRAFTER666Дата: Понедельник, 22.07.2013, 16:46 | Сообщение # 6
Сержант
Группа: Пользователи
Сообщений: 31
Репутация: 0
Статус: Offline
Цитата (xaramamburu)
И охота вам так издеваться.

Мне многие так говорили. Но я люблю изобретать велосипед smile
Цитата (xaramamburu)
Вы хотите, чтоб пользователь мог сам назначать комбинацию клавиш так? И вы хотите определить какую комбинацию он нажал, запомнить ее и в дальнейшем сохранить в INI файле или где то еще так?

Именно так. Я, кстати, извиняюсь. Я выложил скриншот своего окна, а говорю про него, как про Light Alloy smile Перепутал smile
Скриншот Light Alloy вот: http://i46.fastpic.ru/big/2013/0722/7f/bea804c21437bd75f68b705adf071b7f.jpg
Цитата (xaramamburu)
Как я понял саму клавишу вы определять научились

Саму клавишу я умею определять уже давно. Ее виртуальный код приходит в wparam, а скан-код - в lparam. Если VCL, то Msg.wparam и Msg.LParam.
Цитата (xaramamburu)
Если не сложно выложите ссылку на форум.

http://www.programmersforum.ru/showthread.php?s=8260c286e9ed1945e7da6f92754f7fe4&p=1255294
Но там ничего толком не решилось. Мне посоветовали способ с использованием функций CreateAcceleratorTable, DestroyAcceleratorTable, TranslateAccelerator, но позже выяснилось, что при использовании акселераторов в одном окне, вешаются остальные окна, если окон у программы несколько. Видно,  зря я им не сказал, что у меня в проге несколько окон. Хотя модификаторы можно определять в сообщении WM_KEYDOWN с помощью функции GetKeyState, примерно так, как вы предложили (только, я всё-равно не понял, как это мне поможет). А основную проблему с ListView так и не решили. Только протроллили smile Так что, продолжать туда отписываться не вижу смысла.

Цитата (xaramamburu)
В место переменной наверное можно выгрузить в ListView.

Процедура проверки абсолютна аналогична:

Выгрузить-то элементарно. А как связать комбинацию с действием? Неужели только так: case <listview id> of Действие1..9?

Цитата (xaramamburu)
Неплохо было бы посмотреть, а то так сложно о чем то говорить.

Вот код. Позволяет переназначать/сохранять/загружать клавиши для управления окном. Без модификаторов. Написан на WinAPI.

Код
var
   old_lv_kbd_proc : LongInt = 0; // старая процедура

// структура, хранящая коды кнопок
type
   KeyboardConfiguration = record
     SeekLeft : Integer;
     SeekRight : Integer;
     PlayPause : Integer;
     Fullscreen : Integer;
     ControlsPanelVisibility : Integer;
     MakeScreenshot : Integer;
     ConfigFile : string;
   end;

// оконная процедура ListView
function lvkbdProc(wnd:HWND; Msg : uint; Wpar:Wparam; Lpar:Lparam):Lresult;
  stdcall;
var
   n,key : Integer;
   t : string;
Begin
   Result := 0;
   case msg of

     WM_KEYDOWN:
     begin
       n := lv_GetIndex(wnd); // определяем индекс выделенной строки
{      key := (Lpar shr 24);
       settext(form4,IntToStr(key));}
       lv_setItemText(wnd,n,2,IntToStr(Wpar));
       lv_setItemText(wnd,n,1,GetKN(lpar));
       lv_getitemtext(wnd,N,0,t); // достаём текст из первой колонки ListView. N - индекс выделенной строки
//      t := LowerCase(t); // почему-то не работает.
       if t='Плэй / пауза' then
       cfg.KeysConfig.PlayPause := Wpar else
       if t='Перемотка назад' then
       cfg.KeysConfig.SeekLeft := Wpar else
       if t='Перемотка вперед' then
       cfg.KeysConfig.SeekRight := Wpar else
       if t='Полный экран' then
       cfg.KeysConfig.Fullscreen := Wpar else
       if t='Скриншот' then
       cfg.KeysConfig.MakeScreenshot := Wpar else
       if t='Панель управления' then
       cfg.KeysConfig.ControlsPanelVisibility := Wpar;
     end;

   else Result:= callWindowProc(Pointer(old_lv_kbd_proc),wnd,msg,wpar,lpar);
   end;
End;

// сохранение настроенных кнопок в любой текстовый файл
procedure saveKeys;
var
   t : string;
   f : TextFile;
   i,n : Integer;
begin
   n := lv_getcount(LV_KeyboardConfigurator);
   if n>0 then
   begin
     AssignFile(f,cfg.KeysConfig.ConfigFile);
     Rewrite(f);
     for i:=0 to n-1 do
       begin
         lv_getitemtext(LV_KeyboardConfigurator,i,2,t);
         Writeln(f,t);
       end;
     CloseFile(f);
   end;
end;

// загрузка кнопок из файла
procedure LoadKeys;
var
   t: string;
   f : TextFile;
   key,i : Integer;
begin
   if not FileExists(cfg.KeysConfig.ConfigFile) then
   Exit;
   AssignFile(f,cfg.KeysConfig.ConfigFile);
   Reset(f);
   i := 0;
   while not Eof(f) do
   begin
     Readln(f,t);
     if t<>'' then
     lv_setItemText(LV_KeyboardConfigurator,i,2,t);
     key := StrToInt(t);
     lv_getitemtext(LV_KeyboardConfigurator,i,0,t);
       if t='Плэй / пауза' then
       cfg.KeysConfig.PlayPause := key else
       if t='Перемотка назад' then
       cfg.KeysConfig.SeekLeft := key else
       if t='Перемотка вперед' then
       cfg.KeysConfig.SeekRight := key else
       if t='Полный экран' then
       cfg.KeysConfig.Fullscreen := key else
       if t='Скриншот' then
       cfg.KeysConfig.MakeScreenshot := key else
       if t='Панель управления' then
       cfg.KeysConfig.ControlsPanelVisibility := key;
     inc(i);
   end;
   CloseFile(f);
end;

// переназначение оконной процедуры ListView
  old_lv_kbd_proc := SetWindowLong(LV_KeyboardConfigurator,GWL_WNDPROC,
                    LongInt(@lvkbdProc));


Код нубский, но работает smile Только, нельзя изменять модификаторы. Но если в коде программы прописать проверку на заранее придуманный модификатор, то действие сработает только при нажатом модификаторе. А как сделать этот модификатор изменяемым, у меня знаний не хватает. А джедаи колоться не хотят smile


Сообщение отредактировал BLACK_CRAFTER666 - Понедельник, 22.07.2013, 16:46
 
xaramamburuДата: Вторник, 23.07.2013, 13:51 | Сообщение # 7
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
Сразу скажу, что в вашем коде я ни чего не понял, т.к. с winapi, не особо дружу, да и здесь только часть кода, а хотелось бы запустить и посмотреть как это все работает. Кроме этого из этого кода не понятно как пользователь будет изменять настройки клавиш в ListView, здесь как я понял только считывание из него в структуру, причем структура не предусматривает наличие у кнопки модификатора. Если б я это делал на VCL то наверное поступил бы так:
При двойном клике на ListView открывал бы новое окно в котором пользователя просил выбрать комбинацию клавиш для данного действия. Далее отлавливал бы эту комбинацию и сохранял в ListView в одну колонку клавишу, а в другую модификатор. После того как все настройки клавиш закончены, по кнопке сохранить выгружал бы все это в структуру или в соответствующие переменные (да если модификатора у клавиши нет то в переменную записывал допустим 1). Ну а далее при работе просто получаете код клавиши и модификатор (модификатора нет то 1) и сравниваете это с вашей структурой (if структура.клавиша = код клавиши и структура.модификатор = модификатор then действие ). И так по всем комбинациям. ))))
 
BLACK_CRAFTER666Дата: Вторник, 23.07.2013, 14:44 | Сообщение # 8
Сержант
Группа: Пользователи
Сообщений: 31
Репутация: 0
Статус: Offline
Цитата (xaramamburu)
Сразу скажу, что в вашем коде я ни чего не понял, т.к. с winapi, не особо дружу,

А зря) У WinAPI есть некоторые преимущества перед VCL. Я так сразу их все не вспомню, но как пример: winapi не выдаёт экскепшены на ошибки в таком количестве, как VCL. Т.е, вместо того, чтобы просто по-тихому вернуть код ошибки, довольно часто генерируется экскепшен. Тут можно долго спорить, но winapi рулит)
Цитата (xaramamburu)
да и здесь только часть кода, а хотелось бы запустить и посмотреть как это все работает.

Это не вопрос. Могу выложить. Только куда? Google-drive сойдет? Нужны исходники или только exe?
Цитата (xaramamburu)
по кнопке сохранить выгружал бы все это в структуру или в соответствующие переменные (да если модификатора у клавиши нет то в переменную записывал допустим 1). Ну а далее при работе просто получаете код клавиши и модификатор (модификатора нет то 1) и сравниваете это с вашей структурой (if структура.клавиша = код клавиши и структура.модификатор = модификатор then действие ). И так по всем комбинациям. ))))

Т.е, для каждого действия использовать пару переменных - код клавиши и код модификатора? ok. Попробую накатать smile


Сообщение отредактировал BLACK_CRAFTER666 - Вторник, 23.07.2013, 14:46
 
xaramamburuДата: Вторник, 23.07.2013, 15:52 | Сообщение # 9
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
Цитата
Тут можно долго спорить, но winapi рулит

Я и не спорю. Кому как нравится.

Цитата
Т.е, для каждого действия использовать пару переменных - код клавиши и код модификатора?

Да. И можно расширить вашу структуру. Например:
SeekLeft : Integer;
ModifSeekLeft : Integer;

и т.д.
В любом случае нужна пара т.к. модификатор это тоже клавиша и она имеет свой код. И его нужно будет проверять совместно с кодом нажатой клавиши.

Цитата
Это не вопрос. Могу выложить. Только куда? Google-drive сойдет? Нужны исходники или только exe?

Можете скинуть мне на почту xaramamburu@list.ru , желательно с исходниками и exe. ))))
 
BLACK_CRAFTER666Дата: Вторник, 23.07.2013, 16:32 | Сообщение # 10
Сержант
Группа: Пользователи
Сообщений: 31
Репутация: 0
Статус: Offline
Цитата (xaramamburu)
Можете скинуть мне на почту

Скинул) Я кстати, мог бы написать для вашего сайта пару статей по WinAPI. Чтобы, так сказать, расширить содержимое)
 
xaramamburuДата: Вторник, 23.07.2013, 16:57 | Сообщение # 11
Полковник
Группа: Администраторы
Сообщений: 240
Репутация: 26
Статус: Offline
Ок. Только чтоб это было ваше, а не где нибудь содранное с просторов интернета. В крайнем случае чтоб были ссылки на источник, а то потом на форумах народ не доволен, типа воруют инфу а ссылок не делают. Если надо я могу создать категорию или присылайте на почту выложу с указанием авторства.))))
 
BLACK_CRAFTER666Дата: Вторник, 23.07.2013, 18:29 | Сообщение # 12
Сержант
Группа: Пользователи
Сообщений: 31
Репутация: 0
Статус: Offline
Цитата (xaramamburu)
Только чтоб это было ваше, а не где нибудь содранное с просторов интернета.

копировать тексты с других сайтов я не собираюсь. Это будут туториалы на темы типа "как создать окно", "как создать Label", "как создать edit/listBox/ListView" и т.д. И, естественно, я приведу примеры, как работать с каждым из этих контролов и некоторые "фишки" работы с окнами (если это можно так назвать). Многое из этого вы могли видеть в исходниках плеера)) Весь интерфейс и api_*.pas-файлы с макросами я писал сам. Комментарии и весь текст будут полностью мои.
Если хотите обсудить, можно продолжить в личке. Речь не идет об оплате моих статей. Я просто хочу рассказать о WinAPI в доступной форме всё, что я знаю, для тех, кому это может быть интересно. Так как, в интернете о WinAPI написано не особо доходчиво и я сам долгое время не мог допереть до очень простых вещей, таких как перекраска окна.
 
LovizaimДата: Суббота, 26.11.2016, 16:25 | Сообщение # 13
Рядовой
Группа: Пользователи
Сообщений: 1
Репутация: 0
Статус: Offline
Как часто вы сталкиваетесь с проблемой того, что нужно срочно взять у кого-то денег, но в нынешние времена эта задача порой становится невыполнимой. Мы рады сообщить вам, что теперь все ваши проблемы разрешаются довольно легко благодаря “Ловизайм”. https://lovizaim.ru

Преимущества микрокредита “Ловизайм”.
Самое главное преимущество - скорость. Заявка на микрокредит рассматривается буквально за несколько минут, тогда как в банках на это уходит до нескольких дней. Ну и к тому же вы не связываете себя обязательствами на долгое время.

Способы получения денег по успешным заявкам.

Получить наличные можно в любом финансовом офисе денежной системы “Контакт”.
С помощью “Яндекс деньги”.
Через любую удобную вам платежную карту.
Используя безналичный перевод на банковский счет.
Отельное удобство - получить деньги сразу на ваш электронный кошелек “QIWI” или “Webmoney”.
С помощью денежных переводов “Золотая корона”.

Какой бы способ из перечисленных вы не выбрали - деньги вы получите максимально быстро.

“Ловизайм” всегда переживает и заботится о своих клиентах, а потому, если у вас возникли трудности с выплатой вашего займа вовремя, не стоит беспокоиться, просто обратитесь в службу поддержки нашей компании на сайте, и наши сотрудники помогут вам разобраться в трудностях и подскажут условия для продления времени погашения микрокредита.

Оформите заявку на получение займа прямо сейчас! https://lovizaim.ru/anketa.shtml
 
Форум » Delphi » Разное » Управление окном с клавиатуры (как лучше сделать?)
  • Страница 1 из 1
  • 1
Поиск:


Copyright MyCorp © 2024Конструктор сайтов - uCoz