2009-03-05 40 views
7

Tôi có một ứng dụng gọi một số ứng dụng tiện ích khác để cài đặt một số cài đặt cho một thiết bị cụ thể. Ứng dụng tiện ích đó được gọi là sử dụng ShellExecuteEx.Làm thế nào tôi có thể làm cho một cửa sổ quy trình con xuất hiện một cách bình thường trong quá trình của tôi?

Để không gây nhầm lẫn cho người dùng, sẽ tốt hơn nếu đặt cửa sổ của ứng dụng tiện ích ở cửa sổ chính của tôi. Làm thế nào để làm điều này?

Những điều tôi đã cố gắng:

  1. WaitForSingleObjectEx về quá trình sau ShellExecuteEx, INFINITE TIMEOUT - cửa sổ là phương thức, nhưng ứng dụng chính không sơn lại
  2. WaitForSingleObjectEx (vì nó chờ đợi cho các đối tượng duy nhất!) trên quá trình sau ShellExecuteEx, một số thời gian chờ nhỏ, sau đó gọi Peekmessage và DispatchMessage - repaint hiện đang hoạt động, nhưng ứng dụng tiện ích không còn là "phương thức" nữa. Ứng dụng chính phản hồi nhấp chuột, nhấp chuột vào nút, v.v.
  3. BậtWindow (FALSE), sau đó thực hiện phương thứC# 2, sau đó EnableWindow (TRUE) - WORKS !!!, nhưng sau đó, thứ tự z của đơn đăng ký của tôi đã thay đổi. (nó bây giờ dưới một số cửa sổ khác). tại sao?!
+0

Yêu cầu chỉnh sửa: thay đổi tiêu đề thành "Làm thế nào tôi có thể làm cho một cửa sổ quy trình con xuất hiện theo cách thức trong quá trình của tôi?". Tiêu đề hiện tại của bạn không phản ánh sự khác biệt giữa việc tạo một cửa sổ con và chuyển cửa sổ của bạn sang một quy trình khác (xem SetParent()) –

Trả lời

3

Câu trả lời ngắn gọn là không có cách nào liên tục tạo cửa sổ theo phương thức B của luồng B cho một cửa sổ trong chuỗi A, ngay cả khi các chuỗi trong cùng một quy trình. Nếu bạn sở hữu mã cho cả hai cửa sổ, bạn có thể đến gần, nhưng trong trường hợp đó bạn sẽ đạt được kết quả tốt hơn nhiều cho nỗ lực bằng cách đặt tất cả giao diện người dùng của bạn trong một chuỗi.

Nếu bạn cố gắng gợi ý cho người dùng rằng cửa sổ của luồng B là phương thức cho luồng A, có rất nhiều hành vi thứ tự và kích hoạt Z tinh tế mà bạn phải nhận được (như bạn đã chú ý). hiệu ứng -valley của các loại, nơi mà nó rõ ràng cho người dùng rằng cửa sổ của thread B đang cố gắng để được một cái gì đó nó không và do đó có vẻ bị hỏng.

Để tránh điều đó, tôi sẽ áp dụng cách này:

  1. Người dùng nhấp chuột vào "FDA kiểm tra" trong cửa sổ chính của canner.exe. canner.exe cho thấy một hộp thoại phương thức chỉ ra rằng nó đang mở một chương trình bên ngoài ("Mở Cài đặt Botulism ..."). Việc này sẽ vô hiệu hóa cửa sổ chính, v.v. để người dùng biết một tương tác phương thức đang diễn ra.
  2. canner.exe gọi ShellExecuteEx() để bắt đầu botulism.exe.
  3. canner.exe gọi WaitForInputIdle() trên tay cầm được trả về từ ShellExecuteEx(). WaitForInputIdle() sẽ trả về (xấp xỉ, nhưng thường đủ gần) khi botulsim.exe sẵn sàng cho tương tác người dùng. Nếu botulism.exe thường mất năm giây trở lên để hiển thị giao diện người dùng của nó, tôi có thể sử dụng một thời gian chờ ngắn với WaitforInputIdle() trong một vòng lặp và đôi khi xử lý bất kỳ thư đang chờ xử lý nào với PeekMessage()/ProcessMessage().
  4. canner.exe thay đổi văn bản hộp thoại của nó để phản ánh rằng nó đang chờ người dùng đóng botulism.exe ("Đóng Cài đặt Botulism để tiếp tục ...").
  5. canner.exe gọi MsgWaitForMultipleObjects() trong một vòng lặp để đợi cho đến khi botulsim.exe đóng. MsgWaitForMultipleObjects() sẽ trở lại khi các chốt được truyền đi được báo hiệu hoặc khi có các thông báo đang chờ trong hàng đợi của luồng.
  6. Nếu người dùng nhấp vào hộp đóng trong hộp thoại phương thức của canner.exe trong khi canner.exe đang chờ, canner.exe sẽ nhắc người dùng botulism.exe vẫn đang chạy ("Cài đặt Botulism vẫn mở, tiếp tục không?", " Vâng, tôi biết "hoặc" Không, tôi không làm "). Nếu được xác nhận, canner.exe đóng hộp thoại và hủy kiểm tra FDA ban đầu bắt đầu ở bước 1 và trở về vòng lặp tin nhắn của cửa sổ chính.
  7. Khi MsgWaitForMultipleObjects() chỉ ra rằng botulism.exe xong, canner.exe đóng hộp thoại và tiếp tục bình thường với công tác kiểm tra FDA bắt đầu ở bước 1.

Bằng cách này, nếu mọi thứ tiến hành bình thường và nhanh chóng, tương tác cũng có thể liền mạch, nhưng nếu xảy ra sự cố với quy trình con hoặc thứ tự Z bị thay đổi, v.v. sẽ rõ ràng lý do quy trình gốc đang chờ và những gì người dùng cần thực hiện để hủy hoặc tiếp tục với nhiệm vụ anh ta bắt đầu.

+0

Bạn đã bỏ lỡ ý định đã nêu của OP. Anh ấy muốn làm cho nó liền mạch, anh ấy muốn các ứng dụng twp xuất hiện như một. Giải pháp này cho thấy hệ thống ống nước. Sử dụng thuật ngữ của bạn, người dùng cuối không cần phải biết về "botulism.exe". – jdigital

+0

Thật không may là mô hình Windows, và chắc chắn là trình quản lý hộp thoại, đó là tác nhân bình thường của phương thức, không liền mạch trên các ranh giới quy trình. Và nếu tôi phải có một đường may, tôi thích một đường may mạnh mẽ, có thể nhìn thấy với một đường may ẩn mở ra nếu tôi tình cờ đi. –

+0

Bạn nói đúng là không có cách nào trực tiếp/đơn giản để thực hiện việc này. Tuy nhiên, nó gần như chắc chắn có thể thực hiện được. Câu hỏi đặt ra là liệu nó có đáng giá 150 pt hay không. tiền thưởng để dành thời gian làm việc ra các chi tiết.Đó là ít hơn rất nhiều so với phí tư vấn thông thường ;-) – jdigital

0

Hãy xem xét phương pháp tiếp cận của bạn # 3, rất gần với những gì bạn muốn. Tôi nghi ngờ vấn đề là khi các ứng dụng thứ cấp đóng cửa, Windows quyết định rằng nó không muốn khôi phục tập trung vào một cửa sổ bị vô hiệu hóa. Bạn có thể thử kích hoạt lại cửa sổ của mình trước khi điều đó xảy ra nhưng điều đó có thể phức tạp (và không đáng để nỗ lực).

Thay vì tắt cửa sổ trực tiếp, hãy thử vô hiệu hóa cửa sổ bằng cách chỉ bỏ qua đầu vào của người dùng. Vì vậy, thay vì gọi EnableWindow, hãy thay đổi vòng lặp tin nhắn của bạn để lọc ra các thông điệp đầu vào. Cụ thể, nếu

msg >= WM_KEYFIRST || msg <= WM_KEYLAST || msg >= WM_MOUSEFIRST || msg <= WM_MOUSELAST 

thì hãy hủy thư; nếu không, chuyển nó vào vòng lặp công văn bình thường. Những gì bạn đang làm là tạo cửa sổ bị tắt của riêng bạn, nhưng Windows không biết điều đó.

4

Bạn có hai điều để mô phỏng: quyền sở hữu và phương thức.

Để mô phỏng quyền sở hữu: Bạn cần đặt chủ sở hữu cửa sổ quy trình con mới thành cửa sổ của bạn. Điều này sẽ làm giảm bớt bất kỳ vấn đề đặt hàng z nào. Mặc dù tôi không biết liệu điều này có hiệu quả với quy trình khác hay không. Nếu không thì bạn có thể phải đính kèm hàng đợi đầu vào của chuỗi và sau đó gọi nó. Hoặc sử dụng một số kỹ thuật tiêm mã khác.

SetWindowLong <target window handle>, GWL_HWNDPARENT, <new owner handle> 

Để mô phỏng phương thức, tôi nghĩ bạn đang đi đúng hướng với EnableWindow và WaitForSingleObjectEx.

+3

SetWindowLong GWL_HWNDPARENT hoạt động trên các quy trình, nó gia nhập hàng đợi đầu vào cho bạn. –

2

BậtWindow là chính xác, đây thường là cách hộp thư và các cửa sổ "phương thức" khác thực hiện. Đối với thay đổi theo thứ tự, bạn có thể chặn thông báo WM_WINDOWPOSCHANGING và đặt cờ SWP_NOZORDER để ngăn thay đổi thứ tự. Hãy chắc chắn rằng bạn chỉ làm điều này trong khi bạn đang thiết lập EnableWindow (sai).

1

gợi ý Chỉ cần logic,
Có lẽ bạn có thể tạo dạng phương thức vô hình, và từ anh ta sử dụng phương pháp # 1.

+0

Tôi sẽ thử ngay bây giờ. – moogs

Các vấn đề liên quan