2009-03-31 44 views
19

Tôi đấu tranh để hiển thị biểu mẫu thứ hai phía trên biểu mẫu chính mà không làm mất tập trung.Delphi: Hiển thị cửa sổ mà không cần kích hoạt

Tôi đã thử ShowWindow(second.handle, SW_SHOWNOACTIVATE), nhưng biểu mẫu chính mất tiêu điểm. Nếu tôi đặt Visible := false trên cửa sổ thứ hai, cuộc gọi tới ShowWindow không kích hoạt biểu mẫu thứ hai, nhưng cửa sổ bị trống khi hiển thị ...

Có ai có công thức nấu ăn ngon không?

CẬP NHẬT: Những gì tôi đang cố gắng làm, đang hiển thị cửa sổ thông báo tại một sự kiện cụ thể. Điều quan trọng là hình thức chính không mất tập trung bất cứ lúc nào.

+0

Hum ... Một trong những chỉnh sửa của tôi đã biến mất ... Tôi đoán SO có một số vấn đề trước đó ...? – Vegar

Trả lời

24

Có điều gì đó sai với mã của bạn.

Tôi thử mã này, nó hoạt động:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
    Form2.Visible := True; 
end; 

Hãy cẩn thận để sử dụng Visible, không Show! Nếu không, nó sẽ ghi đè lên SW_SHOWNOACTIVATE.

+0

Tôi xin lỗi, nhưng nó vẫn được kích hoạt :-( – Vegar

+0

Tôi sửa đổi câu trả lời của tôi và thử nghiệm nó :) –

+0

Wow, thật tuyệt vời :-) Các thủ thuật có vẻ là để cho phép nhìn thấy được sai tại designtime, và đặt nó thành sự thật sau cuộc gọi đến showwindow(). Cảm ơn! – Vegar

2

Bạn có thể hiển thị cửa sổ (không phương thức) và đặt lại tiêu điểm thành cửa sổ chính.

procedure TMainForm.ButtonClick(Sender: TObject); 
begin 
    OtherForm.Show; 
    SetFocus; 
end; 

Thử nghiệm trên 2006.

này không hiển thị các hình thức khác trên đầu trang. Nhưng nó là rất trực quan để có một cửa sổ trên đầu trang mà không có sự tập trung.

+0

Nhưng điều này là đủ để kích hoạt các sự kiện và datastorage vv, và tôi không muốn ... – Vegar

+0

điều này không hoạt động trong các trường hợp khác nhau, ví dụ nếu bạn đang làm việc (nói chỉnh sửa văn bản) trong một hình thức con của biểu mẫu chính và biểu mẫu chính cần bật lên thông báo. bạn mất bất kỳ ký tự nào bạn đang trong quá trình gõ cộng với việc đặt tiêu điểm trở lại biểu mẫu chính không đặt tiêu điểm trở về hình thức ban đầu con bạn đang chỉnh sửa. Vấn đề này đã ám ảnh tôi trong một thời gian dài cho đến khi tôi thấy DR đơn giản (Tôi nên nghĩ về điều đó) sửa chữa. – DeveloperChris

1

Tôi đã sử dụng này trong quá khứ

SetWindowPos(WindowHandle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 

tôi đã không kiểm tra này với các phiên bản gần đây của Delphi dù ...

1

Nếu có thể, bạn nên cân nhắc sử dụng một số loại mẹo công cụ cửa sổ để hiển thị thông tin thông báo. Một mẹo công cụ sẽ không lấy cắp tiêu điểm từ cửa sổ chính của bạn khi nó được hiển thị hoặc khi người dùng nhấp vào nó. Biểu mẫu thông thường sẽ có đường viền theo mặc định và nếu người dùng nhấp vào đường viền đó, biểu mẫu chính của bạn sẽ mất tập trung.

Dưới đây là một số mã cơ bản để thực hiện việc này. Đầu biến mất khi được gọi tự do; tuy nhiên bạn nên tắt hẹn giờ hơn là sử dụng giấc ngủ.

with THintWindow.Create(nil) do 
    try 
    ActivateHint(MyRect, 'My Notification'); 
    Sleep(DisplayTime); 
    finally 
    Free; 
    end 
+0

Có lẽ đây là cách dễ nhất để đi, nhưng tôi sẽ phải tùy chỉnh gợi ý để hiển thị nhiều hơn là văn bản đơn giản ... – Vegar

1

Ở đây bạn là:

// you have set your 2nd form as non resizable, without border nor title etc... 
    Form2.Enabled := False; // prevent the 2nd form to grab focus even when clicked 
    SetWindowPos(Form2.Handle, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW or SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOMOVE); 
    // be sure to hide it automatically when done as it is disabled... 
+0

Điều này làm cho nó thực sự hiển thị mà không cần thiết lập Biểu mẫu? –

1

Tôi đã làm điều này trong quá khứ, nhưng tôi không có mã vì nó là propietary trong công việc cuối cùng (xin lỗi).

Nếu tôi nhớ tốt, những gì tôi đã làm là:

  1. Từ khách hàng hạng A gọi một thủ tục (hoặc chức năng) mà không thuộc về bất kỳ lớp (một phương pháp Pascal truyền thống).
  2. Từ phương thức đó, hãy gọi một số phương thức trong lớp B không kế thừa từ TForm
  3. Từ phương thức trong B, tạo cá thể của biểu mẫu bật lên P, nhưng không có cha mẹ hoặc chủ sở hữu; và gọi một phương thức trong cá thể.
  4. Từ phương thức được gọi trong cá thể, tự hiển thị.

Mã (bước 3) có thể đi một cái gì đó như thế này:

var p: TPopupForm; 
begin 
    p := TPopupForm.Create(nil); 
    p.ShowWindow; 
    p.Release; 
end; 

Tôi xin lỗi nếu điều này không làm việc, tôi không có Delphi quá.

0

Daniels mã số hoạt động cho đến khi ...

ShowWindow(Form2.Handle, SW_SHOWNOACTIVATE); 
Form2.Visible := True; 

Cho đến hình thức thứ hai của bạn được tạo động. Sau đó, biểu mẫu thứ hai của bạn được đặt ở vị trí 0,0 với chiều rộng và chiều cao mặc định.

Trong giây lát khi ShowWindow được thực hiện, bạn sẽ thấy biểu mẫu thứ hai trên màn hình, biến mất khi dòng tiếp theo được thực thi.

Tôi đang sử dụng mã cho biểu mẫu lớp phủ trong suốt được tạo theo phương pháp nhuộm. Mã sau đây là sự kết hợp của các câu trả lời cho trước và đặt biểu mẫu thứ hai mà không cần kích hoạt trên biểu mẫu gốc.

SetWindowPos(Form2.Handle, HWND_TOP, Left, Top, Width, Height, SWP_NOACTIVATE); 
Form2.Visible := True; 
Các vấn đề liên quan