TN021: Komut ve ileti yönlendirme

Bu Not komut yönlendirme ve gönderim mimarisi yanı sıra genel penceresinde ileti yönlendirme gelişmiş konular açıklanmaktadır.

Visual c++ programlama Kılavuzu genel ayrıntılar burada açıklanan mimarileri için özellikle Windows mesajları, Denetim bildirimleri ve komutlar arasında ayrım başvurun. Bu Not yazdırılan belgelerde açıklanan sorunları çok aşina olan ve sadece çok gelişmiş konular ele varsayar.

Komut yönlendirme ve gönderim mfc 1.0 işlevlerini geliştikçe mfc 2.0 mimarisi

Windows menü komutları, kısayol tuşları ve iletişim-denetim bildirimleri bildirimler sağlamak için aşırı wm_command mesaj var.

Mfc 1.0 üzerinde küçük bir CWnd içinde bir komut işleyici (örneğin, "OnFileNew") vererek inşa yanıt olarak bir özel wm_commanddenilen sınıf türetilmiş. Bu iletiyi göster adlı bir veri yapısı ile birlikte yapıştırılmış olan ve bir çok alanı etkin komut mekanizma içinde sonuç.

Mfc 1.0, Denetim bildirimleri komut iletilerden ayırmak için ek işlevler de sağladı. Bazen bir komutu kimliği bilinen bir 16 bit kimliği komutları gösterilir Komutları normal başlamak--dan CFrameWnd (örn: bir menü seçin ya da çevrilen bir Hızlandırıcı) ve diğer windows çeşitli için yönlendirilir almak.

Çok belgeli arabirim (MDI) uygulanması için sınırlı bir anlamda komut yönlendirme mfc 1.0 kullanılır. (Bir MDI çerçevesi penceresi etkin MDI alt penceresi komutları temsilcisi.)

Bu işlevsellik Genelleştirilmiş ve mfc komutlar nesneleri (sadece pencere) geniş kapsamlı ele alınması sağlamak için 2.0 genişletilmiş. Genişletilebilir bir mimari yönlendirme iletilerini ve sadece komutları işlemek için aynı zamanda bir komutu geçerli durumu yansıtacak şekilde (menü öğeleri ve araç çubuğu düğmeleri gibi) kullanıcı Arabirimi nesneleri güncelleştirmek için yönlendirme komutu hedef yeniden kullanır ve daha resmi bir sağlar.

Komut kimliklerini

Visual c++ programlama Kılavuzu komutu yönlendirme işlemi bağlama açıklama için bkz. Teknik Not 20 adlandırma kimliği hakkında bilgi içerir.

&Genel öneki "NO_" komutunu kimlikleri için kullanırız. Komut, kimlikleri olan gt; = 0x8000. İleti satırını veya durum çubuğunu komut açıklama dizesini STRINGTABLE kaynak olarak komut kimliği aynı kimlikleri ile olup olmadığını gösterir.

Başvuru kaynakları, çeşitli yerlerde kimliği olabilir bir komutu görünür.:

Uygulama kaynağı kodunda kimliği için bir komut çeşitli yerlerde görüntülenir:

Şu anda, sadece uy&gulama komut kimliklerini gerektiren MFC'deki olmak gt; = 0x8000 ise gosub diyaloglar/komutların uygulanması.

Gosub komutları, iletişim kutuları mimarisinde komutunu kullanma

Yönlendirme ve komutları sağlayan komut mimarisi, çerçeve pencereleri, menü öğelerini, araç çubuğu düğmeleri, iletişim çubuğu düğmelerini, diğer kontrol çubukları ve talep ve rota komutları güncelleştirme veya ana komut hedef (genellikle ana çerçeve penceresi) kimliklerini denetlemek için tasarlanan diğer kullanıcı arabirimi öğeleri ile iyi çalışır. Ana komuttan hedefe uygun diğer komut hedef nesnelere komut veya denetimi bildirimleri yönlendirmek.

İletişim denetim denetim kimliği uygun komutu kimliğine atamak (kalıcı veya kalıcı olmayan) bir iletişim komut mimari özelliklerinden bazıları yararlanabilir Bazı ek kod yazmak zorunda destek için iletişim kutuları otomatik değil.

Düzgün çalışması tüm bu özellikleri için komut Kimliklerinizi gt gerektiğini unutmayın; = 0x8000. Bu yana birçok iletişim kutuları aynı kareye yönlendirilir almak, paylaşılan komutları olmalıdır > = 0x8000, paylaşılmayan IDC'ın belirli bir iletişim kutusunda olmalıdır süre < = 0x7FFF.

Normal bir düğme normal kalıcı bir iletişim kutusu ile ilgili komutu kimliği ayarla düğmesinin IDC yerleştirebilirsiniz Kullanıcı düğmeyi seçtiğinizde iletişim (genellikle ana çerçeve penceresi) sahibi gibi diğer komut komut alır. Çünkü bu genellikle başka bir iletişim kutusunu (ilk iletişim gosub) getirmek için kullanılan bu gosub komutu denir.

Ayrıca, sizin iletişim kutusunda CWnd::UpdateDialogControls işlevini çağırın ve ana çerçeve pencerenizin Adres geçmektedir. Bu işlev olacak etkin veya devre dışı bırak iletişim kutusu denetimleri olup komut işleyicileri çerçevede bilgisine göre. Bu işlev otomatik olarak sizin için kontrol çubukları uygulamanızın boşta döngü denir, ama bu özelliği istediğiniz doğrudan normal diyaloglar için çağırmanız gerekir.

ON_UPDATE_COMMAND_UI çağrıldığında

Her zaman bir programın tüm menü öğelerini etkin kontrol durumunu korumak, hesaplama açısından pahalı bir sorun olabilir. Bir ortak kullanıcı popup seçtiğinde menü öğeleri etkinleştir/onay için tekniğidir. CFrameWnd mfc 2.0 uygulaması WM_INITMENUPOPUP ileti işleme ve menüler arasında ON_UPDATE_COMMAND_UI işleyicileri durumları belirlemek için komut yönlendirme mimarisi kullanır.

CFrameWnd de durum çubuğu (ileti çizgi olarak da bilinir) öğe seçili geçerli menüye açıklamak için WM_ENTERIDLE ileti işleme.

Visual c++ tarafından düzenlenmiş bir uygulamanın menü yapısı, WM_INITMENUPOPUP anda kullanılabilen olası komutları göstermek için kullanılır. ON_UPDATE_COMMAND_UI işleyicileri devlet veya bir menü metnini değiştirin veya önce Menü çizilir için Gelişmiş kullanır (gibi dosya mru listesi veya ole fiiller açılır menüsünden), aslında menü yapısını değiştirme.

ON_UPDATE_COMMAND_UI işleme aynı tür araç çubukları (ve diğer kontrol çubukları) yapılan uygulama onun işsiz döngüye girdiğinde. Kontrol çubukları hakkında daha fazla bilgi için bkz: Sınıf kitaplığı başvuru ve Teknik Not 31.

İç içe açılır menüler

Bir iç içe menü yapısı kullanıyorsanız, sen-ecek duyuru ON_UPDATE_COMMAND_UI işleyici açılan ilk menü öğesi için iki farklı durumlarda denir.

İlk açılışı için denir. Bu yana açılır menüler kimlikleri yok ve tüm halk için başvurmak için açılan ilk menü öğesi kimliği kullandığımız gereklidir. Bu durumda CCmdUI nesnesinin m_pSubMenu üye değişkeni null olmayan olacak ve açılır menüsünün üzerine gelin.

Sadece önce pop-up menü öğeleri çekilecek ikinci adı verilir. Bu durumda sadece ilk menü öğesinin kimliğini gösterir ve CCmdUI nesnesinin m_pSubMenu üye değişkeni null olacak.

Bu onun menü öğeleri ayrı pop-up etkinleştirmenize olanak sağlar, ancak bazı menü kullanan kod yazmak gerekir. Örneğin, bir iç içe menü içinde aşağıdaki yapısı ile:

Filegt;
    Yeni >
        Levha (ID_NEW_SHEET)
        Grafik (ID_NEW_CHART)

ID_NEW_SHEET ve ID_NEW_CHART komutları bağımsız olarak etkinleştirilebilir veya devre dışı. "Yeni" popup menüsü iki etkinse etkinleştirilmiş olmalıdır.

Komut işleyici için ID_NEW_SHEET (açılan ilk komutuyla) şöyle:

void CMyApp::OnUpdateNewSheet (CCmdUI * pCmdUI)
{
 nbsp;  Eğer (pCmdUI - > m_pSubMenu! = null)
    {
        / / tüm halk için "Yeni" sayfa ve grafik etkinleştir
        bool bSistemlerde = m_bCanCreateSheet || m_bCanCreateChart;

/ / CCmdUI::Enable olan bir no-op için bu durum, yani biz
        / / ne yapardın yapmanız gerekir.
        pCmdUI - > m_pMenu - > EnableMenuItem (pCmdUI - > m_nIndex,
            MF_BYPOSITION | 
                (bSistemlerde? MF_ENABLED: (MF_DISABLED | MF_GRAYED)));
        return;
    }
    / / yoksa sadece yeni sayfa komutu
    pCmdUI - > Enable(m_bCanCreateSheet);
}

Komut işleyici için ID_NEW_CHART normal güncelleştirme komut işleyicisi ve bakmak gibi bir şey olurdu:

void CMyApp::OnUpdateNewChart (CCmdUI * pCmdUI)
{
 nbsp;  pCmdUI - > Enable(m_bCanCreateChart);
}

On_command ve ON_BN_CLICKED

İletiyi göster makrolar için on_command ve ON_BN_CLICKED ile aynıdır. mfc komuta ve kontrol bildirim yönlendirme mekanizması yalnızca komut kimliği burada yönlendirmek için karar vermek için kullanır. (:BN_CLICKED) denetim bildirim kodu ile denetim bildirimlerini komutları olarak yorumlanır.

Gelişmiş Not: Aslında, tüm denetim bildirim iletilerini komut işleyicisi zinciri gidin. Bu nedenle teknik demek en_change bir denetim bildirim işleyicisi belge sınıf yazmak mümkündür. Bu yana bu özelliğin pratik uygulamalar birkaç özellik ClassWizard tarafından desteklenmez ve özelliğinin kullanımını kırılgan koduna sonuçlanabilir genellikle tavsiye edilmez.

Düğme kontrolleri devre dışı otomatik devre dışı bırakma

İletişim çubuk veya burada CWnd::UpdateDialogControls üzerinde kendi aradığınız bir iletişim kutusunu kullanarak bir düğme denetimi yerleştirirseniz, on_command ya da ON_UPDATE_COMMAND_UI işleyicileri yok düğmelerini otomatik olarak sizin için çerçeve tarafından devreden çıkarılacaktır olduğunu fark edeceksiniz. Bazı durumlarda bir işleyici olması gerekmez, ancak etkin kalması için düğmeyi isteyeceksiniz. Bir kukla komut işleyici (ClassWizard ile yapmak kolay) eklemek için bunu sağlamanın en kolay yolu olduğunu ve bunu hiçbir şey.

İleti penceresinde yönlendirme

Aşağıda biraz daha ileri düzey konular, mfc sınıfları ve nasıl Windows ileti yönlendirme ve diğer konularda onları etkisi açıklanmıştır. Bilgi burada sadece kısaca açıklanmıştır. Sınıf kitaplığı başvuru genel API'ler hakkında ayrıntılı bilgi için bakınız. mfc kitaplık kaynak kodunu uygulama ayrıntıları hakkında daha fazla bilgi için bakınız.

Teknik Not 17 Detayları penceresini Temizleme, çok önemli bir konu için tüm CWndiçin lütfen-türetilmiş sınıflar.

CWnd sorunları

Uygulama üye işlev CWnd::OnChildNotify kanca veya başka iletiler, komutları ve onların üst (veya "sahip") denetim bildirimleri haberdar olmak için alt pencereleri (denetimleri olarak da bilinir) güçlü ve genişletilebilir bir mimari sağlar. Eğer alt pencere (/ kontrol) bir c++ CWnd kendisi, OnChildNotify denir ilk parametreleri ile gelen özgün iletiyi (başka bir deyişle, msg yapısı) sanal işlevi nesnesidir. Alt pencereyi mesajı yalnız bırakın, yemek veya üst (nadir) iletisini değiştirme.

Varsayılan CWnd uygulama aşağıdaki iletileri işleme ve OnChildNotify kanca almak için alt pencere (denetimleri) ilk ileti çatlamak sağlamak için kullanır:

Sen-ecek duyuru OnChildNotify kanca self-draw iletilere sahip çizim iletilerini değiştirmek için kullanılır.

OnChildNotify kanca ek olarak, daha fazla Yönlendirme davranışını kaydırma mesaj var. Kaydırma çubukları ve iletileri wm_hscroll ve wm_vscroll kaynakları hakkında daha fazla bilgi için aşağıya bakınız.

CFrameWnd sorunları

CFrameWnd sınıfı, birçok komut yönlendirme ve kullanıcı arabirimi sağlar uygulama güncelleştiriliyor. Bu öncelikle uygulama (CWinApp::m_pMainWnd) ana çerçeve penceresi için kullanılır, ancak tüm çerçeve pencereler için geçerlidir.

Ana çerçeve penceresi pencere menü çubuğunu ve durum çubuğunu üst veya mesaj hattı. Komut yönlendirme Yukarıdaki tartışma bakın ve WM_INITMENUPOPUP.

CFrameWnd sınıfı, yönetimi etkin görünüm sağlar. Aşağıdaki iletileri etkin görünümü yönlendirilir:

CMDIFrameWnd/CMDIChildWnd sorunları

CFrameWnd MDI çerçevesi pencere sınıflar türetmek hem bu nedenle hem komut yönlendirme ve kullanıcı arabirimi CFrameWndiçinde sağlanan güncelleştirme aynı tür için etkinleştirilir. Tipik bir MDI uygulamasında yalnızca ana çerçeve penceresi (yani, CMDIFrameWnd nesnesi) menü çubuğunu ve durum çubuğunu tutar ve bu nedenle komut yönlendirme uygulaması ana kaynağı.

Genel Yönlendirme etkin MDI child penceresi ilk çatlak komutlarını alır programıdır. Varsayılan PreTranslateMessage işlevleri hem MDI alt pencereleri Hızlandırıcı tabloları (ilk) işlemek ve MDI çerçevesi (ikinci) yanı sıra normal olarak ele TranslateMDISysAccel tarafından (son) standart MDI sistem komutu Hızlandırıcılar.

Kaydırma çubuğu sorunları

Kaydırma-iletiyi işlerken (wm_hscroll/ OnHScroll/wm_vscrollveya /OnVScroll ), sen-meli denemek-e nerede kaydırma çubuğu iletisi geldi dayanmaz işleyicisi kodu yazın. Kaydırma mesajları doğru kaydırma çubuğu denetimleri ya da ws_hscrollgelen bu yalnızca bir genel Windows sorunu değildir / olanws_vscroll kaydırma çubukları değil denetimleri kaydırma.

Mfc, çocuk ya da eşi kaydırılır (her şey kaydırma çubuğu ve pencere kaydırılır alt-üst ilişkisi olabilir aslında) pencerenin kaydırma çubuğu denetimleri izin verecek kadar uzanır. Bu, özellikle paylaşılan kaydırma çubukları ile bölücü windows için önemlidir. Teknik Not 29 için paylaşılan kaydırma çubuğu konularda daha fazla bilgi içeren CSplitterWnd uygulanması hakkında ayrıntılı bilgi için lütfen.

Yan not etmek, türetilmiş sınıfları, nerede oluşturduğunuzda, belirtilen kaydırma çubuğu stilleri tuzak ve Windows geçmedi iki CWnd vardır. Ne zaman bir oluşturma yordamına geçilen, ws_hscroll ve ws_vscroll bağımsız olarak ayarlanabilir, ancak sonra yaratma değildir değiştirilebilir. Tabii ki, doğrudan test etmek veya ws_ ayarlamak?Oluşturdukları pencerenin kaydırma stili bitleri.

CMDIFrameWnd için sen yaratmak ya da LoadFrame geçmesi kaydırma çubuğu stilleri MDICLIENT oluşturmak için kullanılır. Hem kaydırma stilleri ayarladığınızdan emin olun bir kaydırılabilir MDICLIENT alanı (Windows Program Manager gibi) isterseniz (ws_hscroll | ws_vscroll) CMDIFrameWnd oluşturmak için kullanılan stil.

CSplitterWnd için özel paylaşılan kaydırma çubuklarını bölme bölgeleri için kaydırma çubuğu stilleri uygulayın. Statik Bölümlendirici windows için size ya da kaydırma çubuğu stilini ayarla normal değil. Dinamik bölücü windows için kaydırma çubuğu stil kümesi bölecek, yön sütunlara bölebilirsiniz, satırlar, ws_vscroll bölebilirsiniz, yani ws_hscroll için genellikle olacaktır.

Teknik notlar numarasına göre |nbsp; Teknik notlar kategorisine göre

Index