تنشيط Windows متعدد التطبيقات لا يعمل بشكل صحيح

StackOverflow https://stackoverflow.com/questions/802279

  •  03-07-2019
  •  | 
  •  

سؤال

لدي تطبيق Delphi يحتوي على متصفح مستند كنموذج رئيسي. عندما يفتح المستخدم مستندًا ، نفتح نافذة محرر. نريد أن يكون كل محرر مع زر على شريط المهام ، وكذلك النموذج الرئيسي. لقد قمت بتطبيق الكود العادي للقيام بذلك (أدناه) ، ولكن عندما أنقر على النموذج الرئيسي بعد استخدام نافذة المحرر ، يتم ترك المحرر في الأعلى ، بينما يكون التركيز على النموذج الرئيسي. أنا غير قادر على معرفة ما يسبب هذا السلوك.

إعداد المرحلة: أفتح النموذج الرئيسي ونموذج المستند.

  1. انقر على تطبيق آخر ، انقر فوق النموذج الرئيسي ، يبقى النموذج الرئيسي مركّزًا. (يتصرف كما هو متوقع.)

  2. انقر فوق نموذج المستند ، انقر فوق النموذج الرئيسي ، ويعود نموذج المستند إلى الأمام ، ولكنه يظهر غير نشط. (تظهر الصورة نتيجة)

alt text http://www.matthew-jones.com/temp_xfer/titlebarfailure.jpg

الخطوة الأولى ، هذه هي Delphi 2007 ، ولدي في المشروع:

Application.MainFormOnTaskBar := True;

للنموذج الرئيسي ، ليس لدي رمز إضافي.

لنموذج المستند ، لدي

procedure TCommonEditForm.CreateParams(var params: TCreateParams);
begin
  inherited;
  params.WndParent := 0; // GetDeskTopWindow; no diff
end;

لقد حاولت العمل إذا كانت هناك رسالة تجعل هذا يحدث ، لكن لا يمكنني تحديد موقع أي شيء مناسب. لقد بحثت في الرمز عن أي شيء يتعلق بـ "Activate". القرائن ترحيب!

هل كانت مفيدة؟

المحلول

يعمل طلبي في الطريقة التي تصف بها. هنا هو النهج الذي اتبعته. كنت أرغب في العثور على نهج أبسط ولكن لم أفعل.

لقد بدأت بقراءة هذه المقالات. هذا الأول هو كتابة رائعة من قبل بيتر أدناه:

http://groups-beta.google.com/group/borland.public.delphi.winapi/msg/e9f75ff48ce960eb؟hl=en

تم العثور على معلومات أخرى هنا أيضًا ، ولكن هذا لم يثبت أنه حل صالح: لاستخدامي: http://blogs.teamb.com/deepakshenoy/archive/2005/04/26/4050.aspx

في النهاية ، هذا ما انتهى بي.

تتضاعف شاشة البداية الخاصة بي كنموذج رئيسي للتطبيق. النموذج الرئيسي لديه ربطة عنق خاصة لكائن التطبيق. استخدام جميع النماذج الثانوية يجعلني السلوك الذي كنت أبحث عنه.

في كل نموذج أريده في شريط المهام ، أتجاوز CreateParams. أفعل ذلك على نماذج التحرير الخاصة بي وما يراه المستخدمون "النموذج الرئيسي"

procedure TUaarSalesMain.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := GetDesktopWindow;
end;

نموذج "الرئيسي" بقدر ما يتعلق الأمر بـ Delphi يحمل النموذج الرئيسي الحقيقي في وظيفة النشاط. يمكنني استخدام متغير عضو لتتبع التنشيط الأول. ثم في نهاية الوظيفة ، أخفي نموذج البداية ، لكن لا تغلقه. كان هذا مهمًا بالنسبة لي لأنه إذا كان المستخدم يقوم بتحرير مستند وأغلق النموذج الرئيسي ، لم أكن أرغب في إغلاق شاشات التحرير في نفس الوقت. بهذه الطريقة يتم التعامل مع جميع النماذج المرئية كما هي.

    if FFirstActivate = false then
      exit;

    FFristActivate := false;

    /* 
       Main Load code here 
       Update Splash label, repaint
       Application.CreateForm
       etc.
    */


    // I can't change visible here but I can change the size of the window
    Self.Height := 0;
    Self.Width := 0;
    Self.Enabled := false;

    //  It is tempting to set Self.Visible := false here but that is not
    // possible because you can't change the Visible status inside this
    // function.  So we need to send a message instead.
    ShowWindow(Self.Handle, SW_HIDE);

  end;

ولكن لا تزال هناك مشكلة. تحتاج إلى إغلاق نافذة Main/Splash عند إغلاق جميع النماذج الأخرى. لديّ فحص إضافي في إجراءات الإغلاق الخاصة بي لـ Parent <> nil لأنني أستخدم النماذج كإضافات (تشكل أغراض بلدي تعمل بشكل أفضل من الإطارات).

لم يعجبني حقًا استخدام حدث الخمول ، لكنني لا ألاحظ أن هذا السحب على وحدة المعالجة المركزية.

{
  TApplicationManager.ApplicationEventsIdle
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.ApplicationEventsIdle(Sender: TObject;
  var Done: Boolean);
begin

  if Screen.FormCount < 2 then
    Close;
end;

{
  TApplicationManager.FormCloseQuery
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
var
  i: integer;
begin

  for i := 0 to Screen.FormCount - 1 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        if Screen.Forms[i].CloseQuery = false then
        begin
          CanClose := false;
          break;
        end;
      end;
    end;
  end;

end;

{
  TApplicationManager.FormClose
  ---------------------------------------------------------------------------
}
procedure TApplicationManager.FormClose(Sender: TObject;
  var Action: TCloseAction);
var
  i: integer;
begin

  for i := Screen.FormCount - 1 downto 0 do
  begin
    if Screen.Forms[i] <> self then
    begin
      // Forms that have a parent will be cleaned up by that parent so
      // ignore them here and only attempt to close the parent forms
      if Screen.Forms[i].Parent = nil then
      begin
        Screen.Forms[i].Close;
      end;
    end;
  end;

end;

لقد خدمني هذا جيدًا حتى الآن. قمت بإجراء تغيير بسيط لـ Vista لأن أيقونة شاشة "Main/Splash" الخاصة بي كانت لا تزال تظهر. لا أتذكر ما كان عليه. ربما لا أحتاج إلى ضبط العرض والارتفاع والتمكين وإرسال رسالة إخفاء على شاشة الرش. أردت فقط التأكد من عدم ظهوره :-).

كان التعامل مع الأحداث القريبة ضروريًا. إذا كنت أتذكر ذلك بشكل صحيح ، كان هناك حاجة إلى عندما أرسل Windows رسالة إيقاف التشغيل. أعتقد فقط أن النموذج الرئيسي يحصل على هذه الرسالة.

نصائح أخرى

آسف إذا كان هذا غبيًا حقًا ، لكن ليس لديك مجموعة Formstyle على FSStayontop ، أليس كذلك؟ هذا من شأنه أن يفسر هذا السلوك.

ربما أضف هذا في CreateParams

Params.ExStyle := Params.ExStyle OR WS_EX_APPWINDOW;

أو جرب هذا في أي مكان في الكود. أنا أستخدمه في وقت سابق على النماذج. الحدث.

SetWindowLong(Wnd, GWL_EXSTYLE, 
  GetWindowLong(Wnd, GWL_EXSTYLE) or WS_EX_APPWINDOW) ;

الجانب السلبي من هذا هو أنه إذا تم تقليل النموذج الرئيسي إلى الحد الأدنى من النماذج الأخرى ، فهي تخفي Aswell ، ولكن استعد عندما يكون النموذج الرئيسي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top