2016-09-01 52 views
5

Bir TaskDialog'da kullanıcıya gösterilmeden önce bazı değişiklikler yapmam gerekiyor. Windows API çağrılarını, iletişim kutusundaki her denetimin üzerinde çalışmak için kullanmak oldukça basittir. Hangi düğmeyi bulduğumdan emin olmalıyım. Basıldığında, düğmenin vereceği sonucu okuyabileceğim bir yer bulmayı beklerdim.Bir formdaki denetimler arasında yineleme yaparken, belirli düğmeleri nasıl tanımlayabilirim?

başka bir deyişle, 100 değerini döndüren bir değere (Delphi'de, modal sonuç olarak adlandırılır) neden olan bir düğmeye bastığımda, orada ne olduğunu bulmak için arayabileceğim bir API çağrısı olmasını beklerdim. düğmenin "dönüş değeri" olurdu. Henüz böyle bir arama bulamadım.

Ben düğme metni güvenmek istemiyorum ..

İşte ben bugüne kadar ne var.

function EnumWindowsProcToFindDlgControls(hWindow: HWND; _param:LPARAM): BOOL; stdcall; 
var 
    sClassName:string; 
    hBMP:THandle; 
    i:integer; 
begin 
    SetLength(sClassName, MAX_PATH); 
    GetClassName(hWindow, PChar(sClassName), MAX_PATH); 
    SetLength(sClassName, StrLen(PChar(sClassName))); 

    if sClassName='Button' then 
    begin  
     // always 0... 
     i:=GetDlgCtrlID(hWindow); 

     if (i=100) or (i=102) then 
     begin 
      hBmp := LoadImage(HInstance, 'DISA', IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE or LR_LOADTRANSPARENT); 

      SendMessage(hWindow, BM_SETIMAGE, WPARAM(IMAGE_BITMAP), LPARAM(hBmp)); 
     end; 
    end; 

    // keep looking 
    Result:=true; 
end; 

procedure TForm2.TaskDialog1DialogConstructed(Sender: TObject); 
begin 
    EnumChildWindows(TaskDialog1.Handle, @EnumWindowsProcToFindDlgControls, 0); 
end; 

Bir iletişim kutusuyla bunun gibi şeyler yapmak tamamen "saygın" olmadığından şüpheleniyorum.

Bu, Delphi'nin Windows görev diyalogu özelliğinin etrafındaki sarıcı olan VCL TTaskDialog bileşenini kullanan bir Delphi 10 Win32 uygulamasıdır. gösterilmeden önce, bu kodu yürüten OnConstructed olayı harekete geçirilir.

Yardımlarınız için teşekkür ederiz!

+0

Ben kodunuzu okumadım, ama onların kimliğine göre belirli düğmeler tanımlayabilir. Sadece değiştirmek istediğiniz kontrollerin kimliğini bilmek zorundasınız. –

+0

Windows'da görev iletişim rutini tarafından oluşturulduğunda kimlik her zaman 0 olur. –

+0

FWIW, 'SetLength (sClassName, StrLen (PChar (sClassName)));' ve benzeri kodu sClassName: = PChar (sClassName); 'ile değiştirebilirsiniz. Bu aynı şeyi gerçekleştirecek. –

cevap

9

Win32 düğmelerinde "dönüş değerleri" yoktur, bu nedenle bu türden bir değer almak için API yok. Ne düşündüğünüz kesinlikle bir VCL özelliğidir.

Win32 API açısından, bir düğme bir kontrol numarası olabilir ve örneğin MessageBox() durumunda, standart kimlik değerleri vb IDOK, IDCANCEL gibi iletişim düğmeleri atanır. Bir buton tıklandığında ve diyalog kapatıldığında, düğmenin kontrol ID'si fonksiyon dönüş değeri olarak kullanılır.

Ancak, görev diyalogları kontrol kimliklerini kullanmaz, bu nedenle diyalog düğmelerine atanmış bir şey görmezsiniz. Çocuk numaralandırma sırasında

  1. her düğmenin altyazı metnini (GetWindowText()) almak ve ilgilendiğiniz başlıkları ile karşılaştırabilirsiniz Sadece:

    İki yollar geliyor, belirli bir görev iletişim düğmesine tanımlamak için. Standart düğmelerin (TTaskDialog.CommonButtons özelliğinden), yerelleştirilmiş metin kullandığını bilin. Bu, uygulamanın yerel ayarları üzerinde kontrolünüz olmadıkça, standart düğmeleri bulmak için bu uygun bir seçenek yapmaz. Eğer (IsWindowEnabled() kullanarak) bir engelli çocuk pencereyi bulana kadar
  2. iletişim geçici belirli bir kimliği vardır istenen düğmesini devre dışı bırakmayı bir TDM_ENABLE_BUTTON mesaj göndermek, ardından iletişim ait kontrollerini numaralandırmak ve sonra denetimi yeniden etkinleştirin. Daha sonra bulunan pencereyi gerektiği gibi değiştirebilirsiniz. düğme (TDN_BUTTON_CLICKED gibi TTaskDialog.OnButtonClicked etkinlik tetikleyen) (TTaskDialog.Buttons özelliğinden) özel düğmeleri, ID olarak ModalResult özelliği kullanırken, standart düğmeler vb IDCANCEL, IDOK gibi kimlikleri kullanımı üzerinde işlem Task Dialog messages ve Task Dialog Notifications için

    .

    Standart düğmeler için SendMessage() aracılığıyla veya özel düğmeler için TTaskDialogBaseButtonItem.Enabled özelliği aracılığıyla TDM_ENABLE_BUTTON doğrudan gönderebilirsiniz. 2. For

, bu ben denemek çalışır:

uses 
    Winapi.CommCtrl; 

function FindDisabledDlgControl(hWindow: HWND; _param: LPARAM): BOOL; stdcall; 
type 
    PHWND = ^HWND; 
begin 
    if not IsWindowEnabled(hWindow) then 
    begin 
    PHWND(_param)^ := hWindow; 
    Result := False; 
    end else 
    Result := True; 
end; 

procedure TForm2.TaskDialog1DialogConstructed(Sender: TObject); 
var 
    hButton: HWND; 
begin 
    // common tcbOk button 
    SendMessage(TaskDialog1.Handle, TDM_ENABLE_BUTTON, IDOK, 0); 
    hButton := 0; 
    EnumChildWindows(TaskDialog1.Handle, @FindDisabledDlgControl, LPARAM(@hButton)); 
    SendMessage(TaskDialog1.Handle, TDM_ENABLE_BUTTON, IDOK, 1); 
    if hButton <> 0 then 
    begin 
    // use hButton as needed... 
    end; 

    // custom button 
    TaskDialog1.Buttons[0].Enabled := False; 
    hButton := 0; 
    EnumChildWindows(TaskDialog1.Handle, @FindDisabledDlgControl, LPARAM(@hButton)); 
    TaskDialog1.Buttons[0].Enabled := True; 
    if hButton <> 0 then 
    begin 
    // use hButton as needed... 
    end; 
end; 
+0

Detaylı ve yaratıcı cevabınız için teşekkür ederiz (ünlü olarak çalışıyor)! Bu düğme metnine güvenmekten çok daha iyidir (bizim için kabul edilebilir bir durum değil). Bunu da minimum sistemimizde denemeye karar vereceğim ... Bunu yaparak bazı iyi şeyler öğrendim ... –

+0

Kontroller listesinde zaten devre dışı bırakılmış bir düğme varsa, Doğru pencereye sahip olduğunuzu nasıl anlarsınız? –