Genel geçiş ile ilgili sorunlar
Mfc 2.5 (ve üstü) ole 2 sınıfları için tasarım hedefleri çok yerde mfc 2.0 ole 1.0 destek koymak aynı Mimarlık tutulacak biriydi. Bunun sonucunda, mfc 2.0 aynı ole sınıfların çoğu hala mfc (COleDocument, COleServerDoc, COleClientItem, COleServerItem) bu sürümünde mevcut. Ayrıca, birçok API bu sınıflarda tam olarak aynıdır. Ancak, bazı ayrıntılar değişti bekleyebilirsiniz ole 2 ole 0'dan büyük ölçüde farklı. mfc 2.0 In OLE1 desteğiyle biliyorsanız, MFC'ın 2.0 desteği ile evinizde hissedeceksiniz.
Varolan bir mfc/OLE1 uygulama alarak ve ole 2 işlevselliği ekleyerek, bu notu ilk okumalısınız. Bu Not, OLE1 işlevselliği mfc/ole 2 taşıma sırasında karşılaşabileceğiniz ve mfc 0'da bulunan iki uygulamaları taşıma sırasında ortaya çıkarılan sorunları tartışıyor bazı genel sorunları kapsar: mfc ole örnekleri OCLIENT ve HIERSVR.
Mfc belge/görünüm mimarisi önemlidir
Uygulamanızın MFC'ın belge/görünüm mimarisi kullanmaz ve ole 2 desteği uygulamanıza eklemek istediğiniz belge/görünüme taşımak için zaman artık. Uygulamanızın mfc bileşenleri ve dahili mimarisini kullanarak bir kez birçok MFC'ın ole 2 sınıfları yararları yalnızca gerçekleştirilmektedir.
Mfc mimari kullanmadan sunucu veya kapsayıcı uygulamak mümkün, ancak önerilmez.
Mfc uygulaması kendi yerine kullanın
Mfc "konserve uygulanması" CToolBar, CStatusBarve CScrollView gibi sınıfları var ole 2 desteği yerleşik özel durum kodu. Yani, eğer bu sınıflar uygulamanızda kullanabileceğiniz ole farkında yapmak için onları koymak çaba yararlanacaksınız. Yine, burada "rulo kendi" sınıflar için bu amaçla mümkündür, ama değil önerilmektedir. Benzer bir işlevsellik sağlamanız gerekiyorsa, (özellikle yerinde etkinleştirme geldiğinde) mfc kaynak kodu bazı ince noktaları OLE ile başa çıkmak için mükemmel bir referans olduğunu.
Mfc örnek kodu inceleyin
Ole işlevlerini içeren mfc örnekleri vardır. Bu uygulamaların her biri farklı bir açıdan ole uygular:
Çoğunlukla bir sunucu uygulaması olarak kullanmak içindir HIERSVR -. Bu mfc 2.0 mfc/OLE1 uygulama olarak dahil oldu ve mfc/ole 2'ye taşıdık ve sonra bunu uygulayan birçok ole özellikleri ole 2 kullanılabilir şekilde genişletilmiş.
OCLIENT - ole özelliklerin bir kapsayıcı açıdan göstermek amacıyla bir tek başına konteyner uygulaması budur. mfc 2.0'dan çok taşıdık ve ardından birçok özel Pano biçimleri ve bağlantılar katıştırılmış öğeler gibi daha gelişmiş ole özellikleri desteklemek için genişletilmiş.
O does öylesine varolan nesne yönelimli bir çizim programı çerçevesinde dışında olduğunu DRAWCLI - bu uygulama, ole kapsayıcı destek OCLIENT gibi çok uygular. Size nasıl ole kapsayıcı destek ve mevcut uygulamaya entegre gösterir.
superpad - bu uygulamanın yanı sıra iyi bir tek başına uygulama olarak da bir ole sunucusudur. Bunu uygulayan sunucu desteği oldukça minimalist olduğunu. Nasıl verileri Pano'ya kopyalamak için ole Pano Hizmetleri kullanan belirli ilgi olduğunu, ama işlevselliği yerleşik kullanır "Düzenle" denetimi panoya Yapıştır işlevselliğini uygulamak için. Bu ilginç bir karışımı geleneksel Windows API kullanımı yanı sıra yeni ole API'leri ile tümleştirme gösterir.
Örnek uygulamalar hakkında daha fazla bilgi için bkz: "mfc örnek Yardım".
Vaka çalışması: OCLIENT dan mfc 2.0
Yukarıda anlatıldığı gibi OCLIENT mfc 2.0 eklenmiştir ve ole mfc/OLE1 ile uygulanmaktadır. Olan bu uygulamanın başlangıçta mfc/ole 2 sınıfları kullanmak için dönüştürülmüş adımları aşağıda açıklanmıştır. mfc/ole sınıflar daha iyi göstermek için başlangıç noktası tamamlandıktan sonra birkaç özellik eklenmiştir. Bu özellikler burada yer almaz; Bu gelişmiş özellikler hakkında daha fazla bilgi için örnek kendisini bakın.
&Notnbsp; Derleyici hataları ve adım adım işlem Visual c++ 2.0 ile oluşturuldu. Visual c++ 4.0 ile belirli hata iletileri ve konumları değişmiş olabilir, ancak kavramsal bilgiler geçerli kalır.
Almak ve koşma
Yaklaşım mfc/ole OCLIENT örnek bağlantı noktası için alınan bina ve sonuçlanacak bariz derleyici hataları düzeltmeden başlatmaktır. mfc 0'dan OCLIENT örnek almak ve mfc bu sürümü altında derlemek, çözmek için birçok hatalar değildir bulabilirsiniz. Hataları oluştuğu onlar sırayla aşağıda açıklanmıştır.
Derleme ve düzeltme hataları
\oclient\mainview.cpp(104): hata C2660: 'Çizmek': işlev 4 parametre almaz
İlk hata COleClientItem::Drawilgilendiriyor. mfc/OLE1 mfc/ole sürümü alır daha daha fazla parametre aldı. Ekstra Parametreler genellikle gerekli ve genellikle boş (Bu örnekte olduğu gibi). Meta dosyası dc için çizilmiş cdc ne zaman mfc bu sürümü otomatik olarak lpWBounds değerlerini belirleyebilirsiniz. Ayrıca çerçeve özniteliğinden"dc" geçirilen PDC oluşturmak çünkü pFormatDC parametresi artık gerekli değildir. -E doğru saptamak bu problem, sadece iki kaldırın böylece ekstra beraberlik çağrısı parametreleri null.
\oclient\mainview.cpp(273): hata C2065: 'OLE_MAXNAMESIZE': bildirilmemiş tanımlayıcısı
\oclient\mainview.cpp(273): hata C2057: Sabit ifade bekleniyor
\oclient\mainview.cpp(280): hata C2664: 'CreateLinkFromClipboard': 'char [1]' parametre 1 dönüştürmek olamaz ' enum:: tagOLERENDER '
\oclient\mainview.cpp(286): hata C2664: 'CreateFromClipboard': 'char [1]' parametre 1 dönüştürmek olamaz ' enum:: tagOLERENDER '
\oclient\mainview.cpp(288): hata C2664: 'CreateStaticFromClipboard': 'char [1]' parametre 1 dönüştürmek olamaz ' enum:: tagOLERENDER '
Gerekli tüm mfc/OLE1 COleClientItem::CreateXXXX fonksiyonları öğeyi göstermek için benzersiz bir ad geçirilmesi gerçeği yukarıdaki hatalar sonucu. Bu temel ole API zorunlu oldu. ole 2 dde (adı, dde konuşmaları kullanılmıştır) temel iletişim mekanizması olarak kullanmaz çünkü bu mfc/ole 2 gerekli değildir. -E doğru saptamak bu problem, CreateNewName işlevi aynı zamanda başvuruları kaldırabilirsiniz. Ne her mfc/ole işlevi bu sürümde sadece İmlecinizi arama yerleştirme ve F1'e basarak bekliyor bulmak kolaydır.
Önemli ölçüde farklı olan başka bir ole 2 Pano işleme alandır. OLE1 ile API etkileşim Windows Pano Pano ile kullanılır. ole 2 ile bu farklı bir mekanizma ile yapılır. mfc/OLE1 API'ları, COleClientItem bir nesneyi Pano'ya kopyalamadan önce Pano açık üstlendi. Bu, artık gerekli değildir ve tüm mfc/ole pano işlemlerinin başarısız olmasına neden olur. CreateNewNamebağımlılıkları kaldırmak için kod düzenlerken, açar ve kapatır Windows panosuna kodu kaldırmanız gerekir.
\oclient\mainview.cpp(332): hata C2065: 'AfxOleInsertDialog': bildirilmemiş tanımlayıcısı
\oclient\mainview.cpp(332): hata C2064: terim değil değerlendirmek için bir işlev
\oclient\mainview.cpp(344): hata C2057: Sabit ifade bekleniyor
\oclient\mainview.cpp(347): hata C2039: 'CreateNewObject': 'CRectItem' üyesi değil
Bu hatalar CMainView::OnInsertObject işleyicisinden sonucu. "Yeni Nesne Ekle" komutu işleme burada işler biraz değişti başka bir alandır. Bu durumda, sadece orijinal uygulanması için yeni bir ole kapsayıcı uygulama AppWizard tarafından sağlanan ile birleştirme daha kolaydır. Aslında, bu, diğer uygulamaların taşımak için uygulayabileceğiniz bir tekniktir. mfc/OLE1, AfxOleInsertDialog işlevini çağırarak "Nesne Ekle" iletişim kutusu görüntülenir. Bu sürümde COleInsertObject iletişim nesnesi oluşturmak ve DoModalçağırın. Ayrıca, yeni ole maddeler, classname dize yerine bir CLSID ile oluşturulur. Sonuç a?a?ydaki gibi görünmelidir
COleInsertDialog dlg;
Eğer (dlg.DoModal()! = IDOK)
nbsp; return;
BeginWaitCursor();
CRectItem * pItem = null;
DENEYİN
{
/ / c++ nesnesi oluşturmalı
pItem = GetDocument() - > CreateItem();
ASSERT_VALID(pItem);
/ / İletişim verileri maddeden başlatılamıyor.
Eğer (! dlg.CreateItem(pItem))
AfxThrowMemoryException();
/ / herhangi bir istisna yapacağım
ASSERT_VALID(pItem);
/ / Nesne uygunsa run
Eğer (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem - > DoVerb(OLEIVERB_SHOW, this);
/ / hemen güncelleme
pItem - > UpdateLink();
pItem - > UpdateItemRectFromServer();
/ / Yeni eklenen maddeye seçimi ayarla
SetSelection(pItem);
pItem - > Invalidate();
}
catch (CException, e)
{/ Madde temiz
Eğer (pItem! = null)
GetDocument() - > DeleteItem(pItem);
AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH
EndWaitCursor()
&Notnbsp; Yeni nesne eklemeyi uygulamanız için farklı olabilir):
Lt;afxodlgs.h eklemek gereklidir > mfc tarafından sağlanan diğer standart diyaloglar yanı sıra COleInsertObject iletişim sınıf bildirimi içeren.
\oclient\mainview.cpp(367): hata C2065: 'OLEVERB_PRIMARY': bildirilmemiş tanımlayıcısı
\oclient\mainview.cpp(367): hata C2660: 'DoVerb': işlev 1 parametre almaz
Kavram onlar aynı olsa bile aslında bazı OLE1 sabitleri ole 2'de değişti bu hataları kaynaklanır. Bu durumda OLEVERB_PRIMARY OLEIVERB_PRIMARYiçin değişti. Kullanıcı bir öğeyi tıklattığında OLE1 ve ole 2'de birincil fiil genellikle kapsayıcısı tarafından yürütülür.
Ayrıca, DoVerb şimdi ilave bir parametre alır — bir görünüm için bir işaretçi (CView*). Bu parametre, yalnızca "Görsel düzenleme" (veya yerinde etkinleştirme) uygulamak için kullanılır. Çünkü sen şu anda bu özellik uygulama değil şimdi size bu parametre null olarak ayarlamak için.
Çerçevesinde yerinde girişimlerini asla harekete geçirmek emin olmak için COleClientItem::CanActivate aşağıdaki gibi geçersiz
Bool CRectItem::Ca&nActivate()
{
nbsp; return false;
}
\oclient\rectitem.cpp(53): hata C2065: 'GetBounds': bildirilmemiş tanımlayıcısı
\oclient\rectitem.cpp(53): hata C2064: terim değil değerlendirmek için bir işlev
\oclient\rectitem.cpp(84): hata C2065: 'SetBounds()': bildirilmemiş tanımlayıcısı
\oclient\rectitem.cpp(84): hata C2064: terim değil değerlendirmek için bir işlev
Mfc/OLE1, COleClientItem::GetBounds ve setBounds() sorgulamak ve öğeyi ( sol ve üst üyeleri her zaman sıfır idi) ne ölçüde işlemek için kullanılan. mfc/ole 2'de bu daha doğrudan COleClientItem::GetExtent ve SetExtent, hangi bir boyutu veya CSize ile uğraşmak yerine desteklenir.
Sizin yeni SetItemRectToServer kodu ve UpdateItemRectFromServer aramaları bakmak bunun gibi:
Bool CRectItem::UpdateItemRectFromServer()
{
nbsp; ASSERT(m_bTrackServerSize);
CSize büyüklüğü;
if (!.GetExtent(&size))
return false; / / boş
/ / göster HIMETRIC ekran koordinatları
{
CClientDC screenDC(NULL);
screenDC.SetMapMode(MM_HIMETRIC);
screenDC.LPtoDP(&size);
}
/ / sadece madde boyutunu ayarla
Eğer (m_rect.Size()! = boyut)
{
/ / eski Boyut/konum geçersiz
Invalidate();
m_rect.right = m_rect.left + size.cx;
m_rect.Bottom = m_rect.top + size.cy;
/ / hem de yeni boyut/konum
Invalidate();
}
true döndürür;
}
bool CRectItem::SetItemRectToServer()
{
/ / resmi sınırları katıştırılmış madde için ayarlamak
CSize boyutu = m_rect.Size();
{
CClientDC screenDC(NULL);
screenDC.SetMapMode(MM_HIMETRIC);
screenDC.DPtoLP(&size);
}
DENEYİN
{
SetExtent(size); / / bekleme yapabilirsiniz
}
catch (CException, e)
{
return false; / / bağlantılar setBounds() izin vermez
}
END_CATCH
true döndürür;
}
\oclient\frame.cpp(50): hata C2039: 'InWaitForRelease': 'COleClientItem' üyesi değil
\oclient\frame.cpp(50): hata C2065: 'InWaitForRelease': bildirilmemiş tanımlayıcısı
\oclient\frame.cpp(50): hata C2064: terim değil değerlendirmek için bir işlev
OLE1 birçok durumda doğal olarak zaman uyumsuz olduğundan mfc/OLE1 içinde eşzamanlı API çağrıları gelen bir kapsayıcı bir sunucuya benzetilen, vardı. Kullanıcı komutları işlemeyi önce devam eden olağanüstü bir zaman uyumsuz çağrı denetlemek gerekliydi. mfc/OLE1, bunu yapmanız için COleClientItem::InWaitForRelease işlevi sağladı. Böylece hep birlikte CMainFrame OnCommand kılma kaldırmaya mfc/ole 2'de bu gerekli değildir.
OCLIENT bu noktada derleyin ve bağlantı.
Diğer gerekli değişiklikleri
OCLIENT çalışmasını, ancak tutacak yapılan olmayan şeyler vardır. Şimdi yerine daha sonra bu sorunları düzeltmek daha iyidir.
Her şeyden önce ole kitaplıklarının başlatmak gereklidir. Bu InitInstance AfxOleInit arayarak yapılır:
if (!.AfxOleInit())
{
AfxMessageBox ("ole kitaplıkları başlatılamadı");
return false;
}
Sanal işlevler için parametre listesi değişiklikleri denetlemek iyi bir fikirdir. COleClientItem::OnChangeher mfc/ole kapsayıcı uygulama geçersiz kılınmış, böyle bir işlevi olduğunu. Çevrimiçi Yardım bakarak, fazladan bir 'dword dwParam' eklendiğini göreceksiniz. Yeni CRectItem::OnChange gibi görünüyor
void CRectItem::OnChange (OLE_NOTIFICATION wNotification, dword dwParam)
{
Eğer (m_bTrackServerSize amp; ve
!UpdateItemRectFromServer())
{
/ / Boş nesne
Eğer (wNotification == ole_closed)
{
/ / nesne için - alınan veri yok o
ASSERT (!.IsVisible());
GetDocument() - > DeleteItem(this);
return; / / Güncelleme (madde gitti şimdi)
}
}
Eğer (wNotification! = ole_closed)
Dirty();
Invalidate(); / / bir çizmeye herhangi bir değişiklik neden olur
}
Mfc/OLE1, konteyner uygulamaları, belge sınıfı COleClientDoctüretilmiştir. mfc/ole 2'de bu sınıf kaldırıldı yapılmış ve (Bu yeni organizasyon konteyner/sunucu uygulamaları oluşturmak kolaylaştırır) COleDocument tarafından değiştirilir. Orada COleClientDoc mfc/OLE1 uygulamalarının mfc/ole 2, OCLIENT gibi taşımak kolaylaştırmak için COleDocument eşleyen bir # define . Standart komut ileti eşleme girdilerini COleClientDoc tarafından sağlanan COleDocument tarafından sağlanmayan özelliklerden biridir. Böylece bir kapsayıcı/sunucu uygulaması olmadıkları sürece de COleDocument (dolaylı) kullanan sunucu uygulamaları, onlarla bu komut işleyicileri yükünü taşımaz bu yapılır. Böylece, CMainDoc ileti harita aşağıdaki girdileri eklemek gerekir:
ON_UPDATE_COMMAND_UI (ID_EDIT_PASTE, OnUpdatePasteMenu)
ON_UPDATE_COMMAND_UI (ID_EDIT_PASTE_LINK, OnUpdatePasteLinkMenu)
ON_UPDATE_COMMAND_UI (ID_OLE_EDIT_LINKS, OnUpdateEditLinksMenu)
on_command (ID_OLE_EDIT_LINKS, COleDocument::OnEditLinks)
ON_UPDATE_COMMAND_UI (ID_OLE_VERB_FIRST, OnUpdateObjectVerbMenu)
ON_UPDATE_COMMAND_UI (ID_OLE_EDIT_CONVERT, OnUpdateObjectVerbMenu)
on_command (ID_OLE_EDIT_CONVERT, OnEditConvert)
Bu komutların tümünü COleDocumentiçinde temel sınıf belgenizin olduğu uygulamasıdır.
Bu noktada OCLIENT bir işlev ole kapsayıcı uygulamasıdır. (OLE1 veya ole 2) herhangi bir türde öğeler eklemek mümkündür. Yerinde etkinleştirme etkinleştirmek için gerekli kodu uygulanmadı beri öğeleri ayrı bir pencerede çok benzer OLE1 ile düzenlenir. Bir sonraki bölüm ("Görsel düzenleme" denir) yerinde düzenlemeyi etkinleştirmek için gerekli değişiklikleri ele alınmaktadır.
"Görsel düzenleme" ekleme
Yerinde etkinleştirme (ya da "Görsel düzenleme") ole en ilginç özelliklerinden biridir. Bu özellik, sunucu uygulamasının bölümlerini konteynerin kullanıcı arabirimi sağlanan bir daha sorunsuz düzenleme arayüzü için kullanıcı almak sağlar. Yerinde etkinleştirme için OCLIENT uygulamak için bazı özel kaynaklar, bazı ek kod olarak eklenmesi gerekir. Bu kaynaklar ve kodu normalde AppWizard tarafından sağlanan — kodu buraya kadarını doğrudan uygulamadan bir taze AppWizard "Kapsayıcı" desteği ile ödünç oldu aslında,.
Her şeyden önce yerinde etkin olan bir öğe olduğunda kullanılacak menü kaynak eklemek gereklidir. Visual C++'da bu ekstra menüsünde Kaynak IDR_OCLITYPE kaynak kopyalama ve tüm dosya ve pencere halk kaldırarak oluşturabilirsiniz. Gruplara ayrılması belirtmek için dosya ve pencere halk arasında iki ayırıcı çubuk eklenir (o-meli bakmak beğenmek: dosya || Pencere). Ne demek bu ayırıcılar ve sunucu ve konteyner menüleri nasıl birleştirilir hakkında daha fazla bilgi için bkz: "Menüleri ve kaynaklar: menü birleştirme" ole 2 dersleri.
Bir kez sen-si olmak mahluk bu menüler, onlar hakkında bilmek çerçevesinde izin gerekiyor. Bu sizin InitInstance bu belgeyi şablon listesine eklemeden önce belge şablonu CDocTemplate::SetContainerInfo çağırarak yapılır. Belge şablonu kaydetmek için yeni kodu şuna
CDocTemplate * pTemplate = new CMultiDocTemplate ()
nbsp; IDR_OLECLITYPE,
RUNTIME_CLASS(CMainDoc),
RUNTIME_CLASS(CMDIChildWnd), / / standart MDI alt çerçeve
RUNTIME_CLASS(CMainView));
pTemplate - > SetContainerInfo(IDR_OLECLITYPE_INPLACE);
AddDocTemplate(pTemplate)
Visual c++ ile oluşturulan özel yerinde kaynak IDR_OLECLITYPE_INPLACE kaynak olduğu.
Yerinde etkinleştirme etkinleştirmek için her iki CView değiştirmeniz gerekir bazı şeyler vardır (CMainView) türetilmiş sınıf yanı sıra COleClientItem türetilmiş sınıf (CRectItem). Tüm bu geçersiz kılmalar AppWizard tarafından sağlanır ve uygulanması çoğu doğrudan bir varsayılan AppWizard uygulamasından gelecek.
Bu bağlantı noktası ilk adımda, COleClientItem::CanActivatetamamen geçersiz kılarak yerinde etkinleştirme devre dışı bırakıldı. Bu geçersiz kılma, yerinde etkinleştirme sağlamak için kaldırılmalıdır. Ayrıca, null çünkü görünümü yalnızca yerinde etkinleştirme için gerekli sağlamak için tüm aramalar için (orada iki tanesi) DoVerb geçildi. Yerinde etkinleştirme tam olarak uygulamak için DoVerb arama doğru görünüme geçmek gereklidir. Bu çağrılardan biri olan CMainView::OnInsertObject içinde
pItem-> DoVerb(OLEIVERB_SHOW, this)
CMainView::OnLButtonDblClk ise
m_pSelection-> DoVerb(OLEIVERB_PRIMARY, this)
COleClientItem::OnGetItemPositiongeçersiz kılmak gereklidir. Bu öğe yerinde etkin olduğunda konteynerin pencereye göre nereye penceresi sunucu söyler. OCLIENT için uygulama Önemsiz
void CRectItem::OnGetItemPosition (CRect& rPosition)
{
rPosition = m_rect;
}
Sunucuların çoğu da "yeniden boyutlandırma yerinde." dediği uygulamak Bu boyutta ve kullanıcı öğeyi düzenleme sırada taşındı sunucu pencere sağlar. Konteyner, konumu ve boyutu kapsayıcı belge içinde taşıyarak veya yeniden boyutlandırarak pencere genellikle etkiler çünkü bu eylem, yer almalıdır. Uygulanması için OCLIENT tarafından m_rect yeni konumu ve boyutu ile iç dikdörtgen eşitler.
Bool CRectItem::OnChangeItemPosition(const CRectamp; rectPos)
{
ASSERT_VALID(this);
if (!.COleClientItem::OnChangeItemPosition(rectPos))
return false;
Invalidate();
m_rect = rectPos;
Invalidate();
GetDocument() - > SetModifiedFlag();
true döndürür;
}
Bu noktada, bir madde yerinde aktif ve etkin olduğunda, madde taşıma ve boyutlandırma ile başa çıkmak için izin vermek için yeterli kodu, ama orada kullanıcı düzenleme oturumu çıkmayı sağlayacak kodu yok. Bazı sunucularda bu işlevselliği kendileri tarafından işleme escape tuşuna sağlayacak, ancak bu kapsayıcı öğe devre dışı bırakmak için iki yol sağlar önerilmektedir: (1) tıklatarak öğenin dışında ve (2) tarafından escape tuşuna isabet.
Kaçış için anahtar Ekle Visual c++ vk_escape anahtar komutu için eşleyen bir Hızlandırıcı ID_CANCEL_EDIT kaynakları eklendi. Bu komut işleyicisi izler:
/ / Aşağıdaki komut işleyici standart sağlar
/ / klavye bir yerinde iptal etmek için kullanıcı arabirimi
/ / session.void CMainView::OnCancelEdit() düzenleme
{
nbsp; / / Bu görünümde herhangi bir yerinde etkin öğeyi kapatın.
COleClientItem * pActiveItem = GetDocument() - > GetInPlaceActiveItem(this);
Eğer (pActiveItem! = null)
pActiveItem - > Close();
ASSERT(GetDocument()-> GetInPlaceActiveItem(this) == null);
}
Madde dışında nerede tıkladığında durumda işlemek için aşağıdaki kod CMainView::SetSelection başlatmak için eklediğiniz
eğer (pNewSel! = m_pSelection || pNewSel == null)
{
nbsp; COleClientItem * pActiveItem = GetDocument() - > GetInPlaceActiveItem(this);
Eğer (pActiveItem! = null & & pActiveItem! = pNewSel)
pActiveItem - > Close();
}
& nbsp
Bir yerinde etkin olduğunda, odak olmalıdır. Görünümünüzü odağı aldığında odak her zaman etkin öğeye transfer olması bu durumda olduğundan emin olmak için OnSetFocus idare:
/ / OnSetFocus ve OnSize özel işlenmesi gerekir / / ne zaman bir nesne düzenlenmiş yerinde.
void CMainView::OnSetFocus (CWnd * pOldWnd)
{
nbsp; COleClientItem * pActiveItem = GetDocument() - > GetInPlaceActiveItem(this);
Eğer (pActiveItem! = null & &
pActiveItem - > GetItemState() == COleClientItem::activeUIState)
{
/ / aynı görünüm ise, bu madde ile odak ayarlamak gerekir
CWnd * pWnd = pActiveItem - > GetInPlaceWindow();
Eğer (pWnd! = null)
{
pWnd - > SetFocus(); / / don't call temel sınıf
return;
}
}
CView::OnSetFocus(pOldWnd);
}
Görünümü yeniden boyutlandırıldığında kırpma dikdörtgeni değişti etkin öğeyi bildirmek gerekiyor. Bunu yapmak için bir işleyici OnSize için verdiğiniz:
void CMainView::OnSize (UINT nType, int mx, int cy)
{
nbsp; CView::OnSize (nType, MX, cy);
COleClientItem * pActiveItem = GetDocument() - > GetInPlaceActiveItem(this);
Eğer (pActiveItem! = null)
pActiveItem - > SetItemRects();
}
Vaka çalışması: HIERSVR dan mfc 2.0
HIERSVR mfc 2.0 da dahil ve ole mfc/OLE1 ile uygulanmaktadır. Bu Not, kısaca olan bu uygulamanın başlangıçta mfc/ole 2 sınıfları kullanmak için dönüştürülmüş adımları açıklar. mfc/ole 2 sınıflar daha iyi göstermek için başlangıç noktası tamamlandıktan sonra birkaç özellik eklenmiştir. Bu özellikler burada yer almaz; Bu gelişmiş özellikler hakkında daha fazla bilgi için örnek kendisini bakın.
&Notnbsp; Derleyici hataları ve adım adım işlem Visual c++ 2.0 ile oluşturuldu. Visual c++ 4.0 ile belirli hata iletileri ve konumları değişmiş olabilir, ancak kavramsal bilgiler geçerli kalır.
Almak ve koşma
Yaklaşım mfc/ole HIERSVR örnek bağlantı noktası için alınan bina ve sonuçlanacak bariz derleyici hataları düzeltmeden başlatmaktır. mfc 0'dan HIERSVR örnek almak ve mfc bu sürümü altında derlemek (olmasına rağmen fazla OCLIENT örnek) gidermek için birçok hatalar değildir bulabilirsiniz. Bunlar genellikle gerçekleştiği sırada hatalar aşağıda açıklanmıştır.
Derleme ve düzeltme hataları
\hiersvr\hiersvr.cpp(83): hata C2039: 'RunEmbedded': 'COleTemplateServer' üyesi değil
Bu ilk hata sunucular için InitInstance işlevi ile çok daha büyük bir sorunun işaret. Bir ole sunucu için gereken başlatma muhtemelen çalışan get it mfc/OLE1 uygulamanıza yapmak zorundayız en büyük değişikliklerden biri olduğunu. Yapılacak en iyi şey bak ne AppWizard için ole sunucusu oluşturur ve kodunuzu uygun olarak değiştirmek olduğunu. Akılda tutulması gereken bazı noktalar şunlardır:
Ole kitaplıklarının AfxOleInit çağırarak başlatmak için gerekli olan
SetServerInfo sunucu kaynak kolları ve CDocTemplate yapıcısını ayarlayamazsınız runtime sınıfı bilgileri ayarlamak için belge şablonunun nesne arama.
Komut satırında /Embedding varsa, ana uygulama penceresinde gösterme.
Belgeniz için bir GUID gerekir. Bu, belgenizin türüne (128 bit) benzersiz bir tanıtıcıdır. AppWizard sizin için bir tane oluşturacak — bunu burada açıklanan tekniği kullanırsanız yeni kod yeni bir AppWizard oluşturulan sunucu uygulamasından kopyalama, size sadece "bu uygulamadan GUID çalabilir". Yokluksa, sen-ebilmek kullanma GUIDGEN.BIN dizini exe programını.
" COleTemplateServer nesne belge şablonuna COleTemplateServer::ConnectTemplate arayarak" gerekli.
Uygulamanızın tek başına çalıştırdığınızda sistem kayıt defterini güncelleştirin. Bu şekilde, kullanıcının taşırsa.exe uygulamanız için yeni konumundan çalıştıran Windows sistem kayıt veritabanı yeni konumu göstermek için güncellenir.
InitInstanceiçin AppWizard ne oluşturur dayalı bu değişiklikleri uyguladıktan sonra HIERSVR InitInstance (ve ilişkili GUID) aşağıdaki gibi okumalı:
// this is the GUID for HIERSVR documents
static const GUID BASED_CODE clsid =
{ 0xA0A16360L, 0xC19B, 0x101A, { 0x8C, 0xE5, 0x00, 0xDD, 0x01, 0x11, 0x3F, 0x12 } };
/////////////////////////////////////////////////////////////////////////////
// COLEServerApp initialization
BOOL COLEServerApp::InitInstance()
{
// OLE 2 initialization
if (!AfxOleInit())
{
AfxMessageBox("Initialization of the OLE failed!");
return FALSE;
}
// Standard initialization
LoadStdProfileSettings(); // Load standard INI file options
// Register document templates
CDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_HIERSVRTYPE,
RUNTIME_CLASS(CServerDoc),
RUNTIME_CLASS(CMDIChildWnd),
RUNTIME_CLASS(CServerView));
pDocTemplate->SetServerInfo(IDR_HIERSVRTYPE_SRVR_EMB);
AddDocTemplate(pDocTemplate);
// create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;
SetDialogBkColor(); // gray look
// enable file manager drag/drop and DDE Execute open
m_pMainWnd->DragAcceptFiles();
EnableShellOpen();
m_server.ConnectTemplate(clsid, pDocTemplate, FALSE);
COleTemplateServer::RegisterAll();
// try to launch as an OLE server
if (RunEmbedded())
{
// "short-circuit" initialization -- run as server!
return TRUE;
}
m_server.UpdateRegistry();
RegisterShellFileTypes();
// not run as OLE server, so show the main window
if (m_lpCmdLine[0] == '\0')
{
// create a new (empty) document
OnFileNew();
}
else
{
// open an existing document
OpenDocumentFile(m_lpCmdLine);
}
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
return TRUE;
}
Yukarıdaki kod yeni bir kaynak kimliği için IDR_HIERSVRTYPE_SRVR_EMB başvuran fark edeceksiniz. Bu başka bir kap içinde katıştırılmış bir belge düzenlenirken kullanılacak menü kaynaktır. mfc/OLE1 içinde katıştırılmış bir öğeyi düzenlemek için özel menü öğeleri anında değiştirildi. Dosya tabanlı belge düzenlemek yerine gömülü öğeyi düzenlerken tamamen farklı menü yapısı kullanarak çok farklı kullanıcı arabirimleri sağlamak için bu iki ayrı modu kolaylaştırır. Daha sonra göreceğiniz gibi tamamen ayrı menü kaynak bir katıştırılmış nesneyi yerinde düzenleme yaparken kullanılır.
Bu kaynak oluşturmak için Visual c++ kaynak kodu yükleyin ve varolan IDR_HIERSVRTYPE menüsünde Kaynak kopyalayın. Yeni kaynak için IDR_HIERSVRTYPE_SRVR_EMB (AppWizard kullandığı aynı adlandırma kuralı budur) yeniden adlandırın. Sonraki "Dosyayı Kaydet" değiştirme "Dosyasını güncelleştirmek için"; Bu komut kimliği ID_FILE_UPDATEverin. Ayrıca "Dosyasının kopyasını kaydet için"; "Dosyayı Kaydet" değiştirme Bu komut kimliği ID_FILE_SAVE_COPY_ASverin. Her ikisi de bu komutların uygulanması çerçevesinde sağlar.
\hiersvr\svritem.h(60): hata C2433: 'olestatus': 'sanal' izin veri bildirimlerinde
\hiersvr\svritem.h(60): hata C2501: 'olestatus': eksik decl-belirleyicileri
\hiersvr\svritem.h(60): hata C2146: sözdizimi hatası: eksik ';' koyup tanımlayıcı 'OnSetData'
\hiersvr\svritem.h(60): hata C2061: sözdizimi hatası: tanımlayıcı 'OLECLIPFORMAT'
\hiersvr\svritem.h(60): hata C2501: 'OnSetData': eksik decl-belirleyicileri
olestatus türü için yönlendiriyordur beri OnSetData, geçersiz kılma kaynaklanan hatalar vardır. olestatus OLE1 hatalar yoluydu. mfc, genellikle bir hresult hata içeren bir COleException dönüştürür, ancak bu hresult ole 2 değiştirildi. Böylece yapılacak en kolay şey kaldırmak için bu durumda OnSetData kılma artık gerekli.
\hiersvr\svritem.cpp(30): hata C2660: 'COleServerItem::COleServerItem': işlev 1 parametre almaz
COleServerItem yapıcı bir ekstra 'bool' parametre alır. Bu bayrak, COleServerItem nesnelerinde bellek yönetimi nasıl yapılır belirler. true olarak ayarlayarak, bu nesnelerin bellek yönetimi çerçevesinde işleme — artık gerekli olduklarında silme. HIERSVR CServerItem ( COleServerItemtüretilmiş) nesneleri onun yerli verilerinin bir parçası kullanır, bu nedenle bu bayrak false olarak oluştururuz. Bu HIERSVR zaman her sunucu öğesi silinir belirlemek sağlar.
\hiersvr\svritem.cpp(44): hata C2259: 'CServerItem': soyut sınıf örneğini yasadışı girişimi
\hiersvr\svritem.cpp(44): hata C2259: 'CServerItem': soyut sınıf örneğini yasadışı girişimi
Bu hatalar ima CServerItem içinde geçersiz değil 'sanal saf' bazı fonksiyonlar vardır. Büyük olasılıkla bu gerçeği OnDraw'ın parametre listesi değişti kaynaklanır. -E doğru saptamak bu yanlışlık, CServerItem::OnDraw gibi (as well as svritem.h bildiriminde) değiştirme
Bool CServerItem::OnDraw(CDC* pDC, CSizeamp; rSize)
{
/ / düğüm çizmek için ole istek
pDC - > SetMapMode(MM_TEXT); / / hep piksel
return DoDraw (pDC, CPoint(0,0), false);
}
Yeni bir parametre 'rSize' dir. Bu çizim, boyutu doldurmak eğer uygun sağlar. Bu boyutu HIMETRICiçinde olmalıdır. Böylece çerçeve ölçüde almak için OnGetExtent çağırır bu durumda, bu değer doldurmak için uygun değil. Bu çalışma, OnGetExtent uygulanması gerekir:
Bool CServerItem::OnGetExtent(DV&ASPECT dwDrawAspect, CSizeamp; rSize)
{
Eğer (dwDrawAspect! = dvaspect_content)
COleServerItem::OnGetExtent (dwDrawAspect, rSize); return
rSize = CalcNodeSize();
true döndürür;
}
\hiersvr\svritem.cpp(104): hata C2065: 'm_rectBounds': bildirilmemiş tanımlayıcısı
\hiersvr\svritem.cpp(104): hata C2228: sol '.SetRect' class/struct/union türünde olmalıdır
\hiersvr\svritem.cpp(106): hata C2664: ' geçersiz __pascal __far DPtoLP (struct:: tagPOINT __far *, int) __far const ': 1 parametresi dönüştürülemez ' int __far *' için ' struct:: tagPOINT __far *'
CServerItem::CalcNodeSize işlevi madde boyutunu HIMETRIC için dönüştürülür ve m_rectBoundsiçinde depolanır. COleServerItem belgesiz 'm_rectBounds' üyesi yok (kısmen m_sizeExtenttarafından değiştirildi, ancak daha m_rectBounds OLE1 içinde ole 2'de bu biraz farklı bir kullanımı üyenin). Bu üye değişkeni HIMETRIC boyutunu ayarlamak yerine, o dönersiniz. Daha önce uygulanan OnGetExtent, bu dönüş değeri kullanılır.
CSize CServerItem::CalcNodeSize()
{
nbsp; CClientDC dcScreen(NULL);
m_sizeNode = dcScreen.GetTextExtent (m_strDescription,
m_strDescription.GetLength());
m_sizeNode += CSize (CX_INSET * 2, CY_INSET * 2);
/ / set önerilen HIMETRIC boyutu
CSize boyutu (m_sizeNode.cx, m_sizeNode.cy);
dcScreen.SetMapMode(MM_HIMETRIC);
dcScreen.DPtoLP(&size);
Boyut dönmek;
}
CServerItem de COleServerItem::OnGetTextDatageçersiz kılar. Bu işlev, mfc/ole içinde eski ve farklı bir mekanizma ile değiştirilir. mfc ole örnek mfc 3.0 sürümü HIERSVR COleServerItem::OnRenderFileDatakılarak bu işlevselliği uygular. Öylesine sen-ebilmek çıkarmak OnGetTextData kılma bu işlevi bu temel bağlantı noktası için önemli değildir.
Ele değil çok daha fazla svritem.cpp hataları vardır. Onlar are değil "gerçek" hataları — önceki hatalarından kaynaklanan sadece hataları.
\hiersvr\svrview.cpp(325): hata C2660: 'CopyToClipboard': fonksiyonu 2 parametre almaz
COleServerItem::CopyToClipboard , 'bIncludeNative' bayrağı artık desteklememektedir. İlk parametreyi kaldırın böylece yerel veri (veri sunucusu maddenin Serialize fonksiyonu tarafından yazılan) her zaman, kopyalanır. Ayrıca, yanlış döndürmek yerine bir hata olduğunda CopyToClipboard bir özel durum oluşturur. CServerView::OnEditCopy için aşağıdaki kodu
void CServerView::OnEditCopy()
{
nbsp; Eğer (m_pSelectedNode == null)
AfxThrowNotSupportedException();
DENEYİN
{
m_pSelectedNode - > CopyToClipboard(TRUE);
}
CATCH_ALL(e)
{
AfxMessageBox ("kopya başarısız panoya");
}
END_CATCH_ALL}
Daha fazla hatalar vardı daha OCLIENT aynı sürümü için HIERSVR mfc 2.0 sürümü derleme kaynaklanan rağmen vardı aslında daha az değişiklik.
Bu noktada HIERSVR derlemek ve bağlantı ve ole sunucusu olarak, ancak sonraki uygulanacaktır yerinde düzenleme özelliği, işlevi.
"Görsel düzenleme" ekleme
"Görsel düzenleme" (veya yerinde etkinleştirme) bu sunucu uygulama eklemek için orada sadece bir kaç şey size bakmak gerekir:
Menü, oluşturmak için kolay bir kaynaktır. Visual c++ run, IDR_HIERSVRTYPE_SRVR_IP adında bir menü kaynak menüsünde Kaynak IDR_HIERSVRTYPE kopyalayın. Yalnızca Düzen ve Yardım menüsü halk sol menü değiştirin. Menüsünde Düzen ve Yardım menüleri arasında iki ayırıcı eklemek (o-meli bakmak beğenmek: düzenleme || Yardım). Ne demek bu ayırıcılar ve sunucu ve konteyner menüleri nasıl birleştirilir hakkında daha fazla bilgi için bkz: "Menüleri ve kaynaklar: menü birleştirme" ole 2 dersleri.
Bitmap alt araç çubuğu için bir "Server" seçeneği işaretli bir taze oluşturulan AppWizard uygulamasından kopyalayarak kolayca oluşturulabilir. Bu bit eşlemi sonra Visual c++ alınabilir. Bitmap, bir kimlik IDR_HIERSVRTYPE_SRVR_IP emin olun.
Sunucu desteği de üretilen AppWizard uygulamasından COleIPFrameWnd türetilmiş sınıf kopyalanabilir. Her iki dosya, IPFRAME kopyalayın.««cpp ve IPFRAME.H ve projeye ekleyebilirsiniz. LoadBitmap arama IDR_HIERSVRTYPE_SRVR_IP, önceki adımda oluşturduğunuz bitmap başvurduğu emin olun.
Şimdi, tüm yeni kaynaklar ve sınıflar oluşturulur çerçeve (ve bunlar hakkında bilir bu uygulamayı şimdi yerinde düzenlemeyi destekleyen bilir) gerekli kodu ekleyin. Bu SetServerInfo biraz daha fazla parametre InitInstance işlev çağrısı ekleyerek yapılır:
pDocTemplate->SetServerInfo (IDR_HIERSVRTYPE_SRVR_EMB,
IDR_HIERSVRTYPE_SRVR_IP, RUNTIME_CLASS(CInPlaceFrame))
Yerinde çalışmaya hazır olduğunu şimdi de yerinde etkinleştirme destekleyen herhangi bir kap içinde. Ama, orada bir küçük hata kodu hala bakıyorlar. Kullanıcı sağ fare düğmesine bastığında görüntülenen bağlam menüsü, HIERSVR destekler. HIERSVR tamamen açıktır, ama does değil iş ne zaman bir gömme yerinde düzenlemeyi bu menüyü çalışır. Neden bu tek satır kod CServerView::OnRButtonDown sabitlenmiş
pMenu-gt;TrackPopupMenu(TPM_CENTERALIGN | TPM_RIGHTBUTTON,
Point.x, point.y, AfxGetApp() - > m_pMainWnd)
Başvuru fark (AfxGetApp)-gt; m_pMainWnd. Sunucu yerinde etkin olduğunda, bir ana pencere vardır ve m_pMainWnd ayarlanır, ancak genellikle görünmez. Ayrıca, bu pencere, uygulama sunucu tamamen açıkken görüntülenir veya tek başına çalışan MDI çerçeve penceresi ana penceresine ifade eder. Aktif çerçeve penceresine başvurmuyor — hangi yerinde etkin olduğunda COleIPFrameWndtüretilmiş bir çerçeve penceresi. Hatta, düzenleme yerinde mfc bu sürümü, AfxGetMainWndyeni bir işlev eklediğinde doğru etkin pencere almak için. Genellikle, bu işlevi yerine kullanmalısınız AfxGetApp() - > m_pMainWnd. Bu kodu aşağıdaki gibi değiştirmek gerekiyor:
pMenu-gt;TrackPopupMenu(TPM_CENTERALI&GN | TPM_RIGHTBUTTON,
Point.x, point.y, AfxGetMainWnd())
Şimdi minimal fonksiyonel yerinde etkinleştirme için etkin ole sunucusu var. Ancak kullanılabilecek hala birçok özellikleri vardır, mfc/OLE1 içinde kullanılamayan mfc/ole 2. Bkz: HIERSVR örnek daha fazla fikir için özellikleri uygulamak isteyebilirsiniz. HIERSVR uygulayan özelliklerden bazıları aşağıda listelenmiştir
HIERSVR örnek mfc 3.0 Ayrıca, kendi sunucusu öğeler için biraz farklı bir tasarım kullanır. Bu bellek tasarrufu sağlar ve bağlantılarınızı daha esnek hale getirir. HIERSVR 2.0 sürümü ile her düğüm ağacında ise bir COleServerItem. COleServerItem kesinlikle bu düğümlerin tümünde gerekli olandan biraz daha fazla yük taşıyan, ancak bir COleServerItem her etkin bağlantı için gereklidir. Ama çoğunlukla, çok az etkin bağlantılar vardır her zaman. Bu daha verimli hale getirmek için HIERSVR mfc bu sürümünde düğüm COleServerItemayırır. Bu hem bir CServerNode hem de bir CServerItem sınıfı vardır. CServerItem ( COleServerItemtüretilmiş) yalnızca gerektikçe oluşturulur. Konteyner (ya da konteyner) belirli düğüm için belirli bağlantı kullanmayı durdurmak sonra CServerNode ile ilişkili CServerItem nesnesi silinir. Bu tasarım, daha verimli ve daha esnektir. Esnekliği zaman birden çok seçimi bağlantılarıyla ilgili oluyor. Bu iki yorum-in HIERSVR hiçbiri birden çok seçimi destekler, ama o-cekti var olmak çok daha kolay eklemek (ve bağlantılar gibi seçimlere destek) HIERSVR beri COleServerItem yerel verileri ayrılmış, mfc 3.0 sürümü ile.
Teknik notlar numarasına göre |nbsp; Teknik notlar kategorisine göre