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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 14.02.2016, 18:38   #1
Kovalchuk.Dmytro
 
Регистрация: 16.01.2015
Сообщений: 7
Вопрос Автодополнение работает неправильно в TMemo

Доброго времени суток! Разрабатываю программу, которая выглядит как командная строка, в которую будет вводится команды в поле свиду напоминающее TEdit, на самом то деле работа идет с TMemo. Так вот когда я ввожу комманду, проводится поиск с файла истории(ранее введенных комманд) и предлагает вариант... все хорошо работает и выделение работает правильно. Но только стоит мне продолжить писать как выделение пропадает меня переносит в конец строки и вводимый символ появляется в конце строки, что не есть хорошо, а каждый раз нажимать бекспейс, если нужна другая комманда неудобно... Ниже код формы строки ввода..
Код:
unit uCommand;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Menus;

type
  TfrmCommand = class(TForm)
    tray: TTrayIcon;
    TrayMenu: TPopupMenu;
    nExit: TMenuItem;
    nSettings: TMenuItem;
    mmCommand: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure nExitClick(Sender: TObject);
    procedure mmCommandKeyPress(Sender: TObject; var Key: Char);
    procedure mmCommandKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure mmCommandChange(Sender: TObject);
    procedure mmCommandKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    procedure OnHotKey(var Msg: TWMHotKey); message WM_HOTKEY;

    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmCommand: TfrmCommand;

implementation

{$R *.dfm}

uses uSettings;

procedure TfrmCommand.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  UnregisterHotKey(Handle, 1);
end;

procedure TfrmCommand.FormCreate(Sender: TObject);
begin
  RegisterHotKey(Handle, 1, MOD_Control+MOD_Shift, Ord('U'));
end;

procedure TfrmCommand.mmCommandChange(Sender: TObject);
var i, position:integer;
    com, buf:string;
    _history:TStringList;
begin
  if mmCommand.Tag=1 then exit;
  _history:=TStringList.Create; TRY
    _history.LoadFromFile(ExtractFilePath(application.ExeName)+'history.dat', TEncoding.Unicode);
    if _history.Count<>0 then for i := 0 to _history.Count-1 do begin
      buf:=_history[i];
      if pos(mmCommand.Text, buf)=1 then begin
        position:=mmCommand.SelStart; com:=mmCommand.Text; mmCommand.Text:=buf;
        mmCommand.SelStart:=position; mmCommand.SelLength:=Length(buf)-Length(com);
        mmCommand.Tag:=1; break;
      end;
    end;
  FINALLY FreeAndNil(_history); END;
end;

procedure TfrmCommand.mmCommandKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key=VK_BACK)or(Key = VK_DELETE)or((ssCtrl in Shift)and((Key=ord('Z'))or(Key=ord('X'))or(Key=ord('V'))))
  then mmCommand.Tag:=1 else mmCommand.Tag:=0;
end;

procedure TfrmCommand.mmCommandKeyPress(Sender: TObject; var Key: Char);
var command:string;
    _history:TStringList;
begin
  _history:=TStringList.Create; TRY
    _history.LoadFromFile(ExtractFilePath(application.ExeName)+'history.dat', TEncoding.Unicode);
    if Key='|' then frmCommand.Hide;
    if Key=#13 then begin
      command:=trim(mmCommand.Text); _history.Insert(0, command); mmCommand.Text:='';
      if command='.close' then frmCommand.Close;
      if command='.hide' then frmCommand.Hide;
      if command='.settings' then begin
        frmSettings.Show; frmCommand.Hide;
      end;
    end;
  _history.SaveToFile(ExtractFilePath(application.ExeName)+'history.dat', TEncoding.Unicode);
  FINALLY FreeAndNil(_history); END;
end;

procedure TfrmCommand.mmCommandKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var buf:string;
begin
  if Key=32 then begin//отменяем нажатие клавиши "пробел"
    buf:=mmCommand.Text; delete(buf, Length(buf), 1); mmCommand.Text:=buf;
    mmCommand.SelStart:=Length(mmCommand.Text);
  end;
end;

procedure TfrmCommand.nExitClick(Sender: TObject);
begin
  frmCommand.Close;
end;

procedure TfrmCommand.OnHotKey(var Msg: TWMHotKey);
begin inherited;
  frmCommand.Show; frmCommand.SetFocus; mmCommand.Text:='';
end;

end.
Kovalchuk.Dmytro вне форума Ответить с цитированием
Старый 14.02.2016, 20:16   #2
kropotkina-alice
Форумчанин
 
Аватар для kropotkina-alice
 
Регистрация: 27.10.2014
Сообщений: 594
По умолчанию

Цитата:
Сообщение от Kovalchuk.Dmytro Посмотреть сообщение
Но только стоит мне продолжить писать как выделение пропадает меня переносит в конец строки и вводимый символ появляется в конце строки
Просто запоминайте позицию курсора после ввода очередного символа и при последующем вводе сначала очищайте поле ввода, начиная с запомненной позиции...
Если я не ошибаюсь, то позицию вы вычисляете:
Код:
position:=mmCommand.SelStart;
Сделайте эту переменную глобальной, чтобы ее было видно всем процедурам.

Последний раз редактировалось kropotkina-alice; 14.02.2016 в 20:23.
kropotkina-alice вне форума Ответить с цитированием
Старый 14.02.2016, 20:34   #3
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

Цитата:
Сделайте эту переменную глобальной, чтобы ее было видно всем процедурам.
Я бы посоветовал сделать это переменную не глобальной, а полем объекта TfrmCommand, из методов которого к ней осуществляется доступ.

P. S. Тему не читал, просто считаю использование глобальных переменных плохим тоном. Сорри за большой офтоп.
Вадим Мошев вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
неправильно работает программа CppForYou Общие вопросы C/C++ 0 26.04.2013 01:13
автодополнение кода vs2010 Snake22 Visual C++ 1 11.07.2012 17:06
sscanf() неправильно работает BioS Общие вопросы C/C++ 7 06.02.2010 22:36
Неправильно работает WinExec? TwiX Общие вопросы Delphi 2 26.11.2009 21:07
TMemo не работает УДИЛИТЬ СТРОКУ Yuran Общие вопросы Delphi 10 12.06.2008 18:48