Czy jest zamiennik InputQuery z polskimi przyciskami?

0

Witam.

Czy jest jakiś zamiennik InputQuery z polskimi przyciskami? Czy trzeba sobie go zrobić coś jak w przykładach Tylko cyfry w InputQuery.

Pozdrawiam.

2

Musisz kodzić wyspany lub nie po alko, bo nie patrzysz w kod ;) Jakiś czas temu pisałem dla Ciebie kod do klienta FTP. Tam masz zamienianie "Cancel" w InputBox na "Anuluj". Także nie problem sobie ten kod dostosować też do InputQuery, wyenumerować kontrolki i ponadawać im odpowiednie etykiety.

Także widzisz, nawet nie patrzysz w kody, które masz na dysku. Ja rozumiem jakieś mało ambitne lamki nie kombinujące do bólu i nie szukające na sieci, tylko lecą ze wszystkim od razu tutaj smarując post na forum. Ale byłem przekonany, że Ty nie jesteś z "pierwszej łapanki" :) Ok. Dla przypomnienia mały wycinek:

//...
const
  PL_Cancel_Btn_Caption = 'Anuluj';
  Custom_InputBox_Message = WM_USER + 2014;
//...
  private
    procedure CustomInputBox(var AMsg : TMessage); message Custom_InputBox_Message;
//...
procedure TFTPForm.CustomInputBox(var AMsg : TMessage);
var
  InputBoxHandle, CancelBtnHandle : HWND;
begin
  InputBoxHandle := Screen.Forms[0].Handle;
  if InputBoxHandle > 0 then
  begin
    CancelBtnHAndle := FindWindowEx(InputBoxHandle, 0, 'TButton', nil);
    if CancelBtnHandle > 0 then
    begin
      SendMessage(CancelBtnHandle, WM_SETTEXT, 0, Integer(PChar(PL_Cancel_Btn_Caption)));
    end;
  end;
end;

//...

procedure TFTPForm.CreateDirOnFTPBtnClick(Sender : TObject);
begin
  PostMessage(Handle, Custom_InputBox_Message, 0, 0);
  FNewDirName := InputBox('Nowy katalog na FTP',
    Format('Nazwa do utworzenia w "%s":', [FDirName]), '');
  if FNewDirName <> '' then
  begin
    CreateDirOnFTPBtn.Enabled := False;
    ActiveThr := TGetContentThr.Create(ctCreateDir);
  end;
end;
//...

EDIT: przykład, że się da też tak:

unit Unit1;

interface

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

const
  WM_MY_INPUTQUERY = WM_USER + 2015;

type
  TForm1 = class(TForm)
    Button1 : TButton;
    Memo1 : TMemo;
    procedure Button1Click(Sender : TObject);
  private
    ControlCnt : integer;
    procedure CustomInputQuery(var AMsg : TMessage); message WM_MY_INPUTQUERY;
  public
  end;

var
  Form1 : TForm1;

implementation

{$R *.dfm}

function EnumChildWinProc(AHandle : HWND) : boolean; stdcall;
var
  ControlName, ControlText : array[0..255] of Char;
begin
  Result := True;
  GetClassName(AHandle, ControlName, SizeOf(ControlName));
  SendMessage(AHandle, WM_GETTEXT, SizeOf(ControlText), integer(@ControlText));
  with Form1 do
  begin
    case ControlCnt of
      0 :
        begin
          TButton(FindControl(AHandle)).Width := 100;
          SendMessage(AHandle, WM_SETTEXT, 0, Integer(PChar('Chodż tu Szogunie')));
        end;
      1 :
        begin
          SendMessage(AHandle, WM_SETTEXT, 0, Integer(PChar('Ale urwał')));
        end;
    end;
    Memo1.Lines.Add(IntToStr(ControlCnt) + ': ' + ControlName + ' - ' + ControlText);
    ControlCnt := ControlCnt + 1;
  end;
end;

procedure TForm1.CustomInputQuery(var AMsg : TMessage);
var
  InputQueryHandle : HWND;
begin
  InputQueryHandle := Screen.Forms[0].Handle;
  if InputQueryHandle > 0 then
  begin
    with Form1 do
    begin
      ControlCnt := 0;
    end;
    EnumChildWindows(InputQueryHandle, @EnumChildWinProc, 0);
  end;
end;

procedure TForm1.Button1Click(Sender : TObject);
var
  S : string;
begin
  PostMessage(Handle, WM_MY_INPUTQUERY, 0, 0);
  if InputQuery('Test', 'Napisz cokolwiek', S) then
  begin
    Caption := S;
  end;
end;

end.

Jeżeli taka metoda Tobie nie odpowiada to pozostaje raczej stworzenie własnej kontrolki o takiej funkcjonalności. Ale nie wiem czy jest sens babrać się z tym i wywazać już otwarte drzwi :)

A i jak widać po enumeracji, TLabel z promptem w Memo się nie pokaże, bo wiadomo że to kontrolka nie mająca uchwytu. Ale to nie problem w razie czego bo mamy Screen.Forms[0].ControlCount i dzięki temu można sobie dostać się do każdej kontrolki VCL również w taki sposób, mając jak w Controls[Index].

0

@olesio dzięki i pewnie masz rację chociaż wystarczyło powiedzieć że trzeba samemu i bym sobie coś dynamicznego wstawił .. ale nie ma tego złego jest kod dla potomnych. A tak z innej beczki używasz jakiegoś programu do katalogowania projektów? Bo ja nie pamiętam co miałem w projekcie pisanym pół roku temu a co dopiero 1-2 lata wstecz.

1

Spoko. Podałem kod, bo może ktoś kiedyś będzie szukał. Ale na Google na 100% i to nie na jednej stronie jest przykład do ustawienia TEdit w InputBox jak do podawania hasła czyli z *. Co do tego czy mam coś co pozwala mi ogarnąć projekty. To nie mam. Cżęsto pomaga mi odnaleźć coś w tych starszych w sumie tylko Alt+F7 pod Total Commanderem. Albo odpalam sobie FAR'a gdzie w odróznienia od TotalCmd mam sortowanie również dla katalogów i patrze w najnowsze gdy coś tam musze sprawdzić w ostatnich kodach w widoku z Ctrl+F5 malejąco.

Faktem jest, że przydało by się notować w jakichś choćby txt co zawiera dany katalog albo stosować ich opisy. Jednak w znalezieniu czegoś w kodach projektów, które sam używam częściej nie stanowi problemu. Gorzej jest, gdy zdarzy się sytuacja gdy ktoś pyta tutaj ogólnikowo o jakieś rozwiązania i pamiętam, że coś chyba takiego kodziłem. Ale projekt był tylko zapisany po wklejeniu go na forum, to wtedy jest ciężko przypomnieć sobie jego nazwę kiedyś tam nadaną.

Przykładowo ostatio rzeźbiłem kod do tworzenia katalogu na własnym koncie w chomikuj.pl. I patrzyłem na kod niedziałającego już downloadera, a nie spostrzegłem że katalog niżej miałem inny przykład, gdzie logowanie nadal działa i nie musiał bym mozolnie przerabiać czyjegoś niedopracowanego kodu logowania na chomikuj.pl tylko do mojego dodać tworzenie folderu. Co nie było trudne ponieważ wszystko widać było pod WireSharkiem jak na dłoni.

Btw, kiedyś stosowałem też zbiorczy plik txt jeszcze pisząc pod Delphi 3, gdzie po komentarzach wklejałem dla mnie ważne przykłady jakichś rozwiązań. Ale to też nie zdaje rezultatu. Bo wiadomo, plik się rozrośnie i ciężko też wszystko w nim sprawnie znaleźć. Porzuciłem to rozwiązanie.

Podsumowując nic nie stosuje w zasadzie, jak na programiste amatora staram się sobie jakoś radzić. Może ktoś tutaj lepiej zorganizowany i doświadczony coś doradzi do ogarnięcia tego co jest w danym projekcie. Dobrym nawykiem jest napsianie sobie modułów oraz klas ogarniających pewne rzeczy powtarzające się w naszych projektach. Tak sobie stworzyłem choćby useful_winapi.pas, gdzie mam najważniejsze dla mnie rzeczy z VCL, które potrzebuje pisząc pod WinAPI.

0

Poukładane moduły od jakiegoś czasu staram się stosować ale i tak te rzadziej stosowane elementy umykają. Co do pozostałych rzeczy to fakt w danej chwili się pamięta a potem jest jak widać na obrazku. Trzeba z tym zrobić porządek. Więc i tu dzięki za cenne wskazówki.

2

A moze tak? Wtedy masz zlatwione wszystkie dialogi (yes zamienia sie na tak / No na nie etc)

 
procedure HookResourceString(RS: PResStringRec; AStr: PWideChar);

procedure HookResourceString(RS: PResStringRec; AStr: PWideChar);
var
  OldProtect: DWORD;
begin
  VirtualProtect(RS, SizeOf(RS^), PAGE_EXECUTE_READWRITE, @OldProtect);
  RS^.Identifier := Integer(AStr);
  VirtualProtect(RS, SizeOf(RS^), OldProtect, @OldProtect);
end;

i teraz uzycie

 
var
  P: PWideChar;
begin
  P := PWideChar('Tak');
  HookResourceString(@SMsgDlgYes, P);

  P := PWideChar('Nie');
  HookResourceString(@SMsgDlgNo, P);
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1