home *** CD-ROM | disk | FTP | other *** search
/ The Houseplan Collection / HRCD2005.ISO / data1.cab / Zusatz / 3DS / DATA2.Z / OEMDlg.cpp < prev    next >
C/C++ Source or Header  |  1999-10-13  |  19KB  |  608 lines

  1. // OEMDlg.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "OEM.h"
  6. #include "OEMDlg.h"
  7. #include "ObjectListDlg.h"
  8.  
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. // COEMDlg dialog
  18.  
  19. COEMDlg::COEMDlg(CWnd* pParent /*=NULL*/)
  20.     : CDialog(COEMDlg::IDD, pParent)
  21. {
  22.     //{{AFX_DATA_INIT(COEMDlg)
  23.         // NOTE: the ClassWizard will add member initialization here
  24.     //}}AFX_DATA_INIT
  25.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  26.   m_pArCon = NULL;
  27. }
  28.  
  29. COEMDlg::~COEMDlg()
  30. {
  31.   if (m_pArCon)
  32.     m_pArCon->Release();
  33. }
  34.  
  35. void COEMDlg::DoDataExchange(CDataExchange* pDX)
  36. {
  37.     CDialog::DoDataExchange(pDX);
  38.     //{{AFX_DATA_MAP(COEMDlg)
  39.         // NOTE: the ClassWizard will add DDX and DDV calls here
  40.     //}}AFX_DATA_MAP
  41. }
  42.  
  43. BEGIN_MESSAGE_MAP(COEMDlg, CDialog)
  44.     //{{AFX_MSG_MAP(COEMDlg)
  45.     ON_WM_PAINT()
  46.     ON_WM_QUERYDRAGICON()
  47.     ON_WM_CLOSE()
  48.     ON_WM_SIZE()
  49.     ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
  50.     ON_WM_MOVE()
  51.     ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
  52.     ON_BN_CLICKED(IDC_ARCON_VISIBLE, OnArconVisible)
  53.     ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
  54.     ON_BN_CLICKED(IDC_VISIBLE, OnObjectsVisible)
  55.     //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57.  
  58. /////////////////////////////////////////////////////////////////////////////
  59. // Hilfsdeklarationen und Funktione
  60. #define PI      3.1415926f
  61. #define TWOPI   (PI * 2.0f)
  62.  
  63. struct Point {
  64.   float x, y, z, u, v;
  65. };
  66.  
  67. typedef Point ConturType[4];
  68.  
  69. static void PointsToVariant(ConturType &contur, VARIANT &v)
  70. {
  71.   // Das C-Array in ein OLE SafeArray konvertieren
  72.   SAFEARRAY * array;
  73.   SAFEARRAYBOUND bounds[2];
  74.   bounds[0].lLbound = 0;
  75.   bounds[0].cElements = 5;
  76.   bounds[1].lLbound = 0;
  77.   bounds[1].cElements = 4;
  78.   array = SafeArrayCreate(VT_R4, 2, bounds);
  79.   void * mem = NULL;
  80.   SafeArrayAccessData(array, &mem);
  81.   memcpy(mem, contur, sizeof contur);
  82.   SafeArrayUnaccessData(array);
  83.  
  84.   VariantInit(&v);
  85.   v.vt = VT_ARRAY|VT_R4;
  86.   v.parray = array;
  87. }
  88.  
  89. // Diese Methode schlie▀t die Konstruktion eines 3D Objektes (ⁿbergeben als "const")
  90. // ab indem es die Transformationsmatrix zur Positionierung in der Welt bildet und
  91. // dann das Objekt entweder in die "reale" Welt einsetzt - und damit ArCon die weitere
  92. // Verwaltung ⁿberlΣ▀t, oder es an eine 2D-Eratzdarstellung bindet, und es damit
  93. // selbst verwaltet. Da in diesem Demo eine 2D-Ersatzdarstellung nicht wirklich gewollt
  94. // ist, wird ein quasi unsichtbares 2D Objekt gebildet: eine Linie ohne LΣnge. Ein
  95. // 2D Objekt, das nicht "visible" wΣre, wⁿrde nicht funktionieren, da die Sichtbarkeit
  96. // der 2D Ersatzdarstellung auch die Sichtbarkeit des 3D Objektes steuert. Die 2D Darstellung
  97. // kann z.B. durchaus einem Gescho▀ zugeordnet werden und nur in diesem erscheint dann das
  98. // 3D Objekt.
  99. void COEMDlg::InstanceIntoWorld(IObjectConstructor* constr, float x, float y, float z, BOOL intoWorld)
  100. {
  101.   USES_CONVERSION;
  102.  
  103.   // Eine Einheitsmatrix als "model to world" Transformation
  104.   float m2w[4][4];
  105.   memset(m2w, 0, sizeof m2w);
  106.   int i;
  107.   for (i = 0; i < 4; i++)
  108.     m2w[i][i] = 1.0f;
  109.   
  110.   // Translation zu (x,y,z), damit nicht alles auf einem Haufen landet
  111.   m2w[3][0] = x;
  112.   m2w[3][1] = y;
  113.   m2w[3][2] = z;
  114.  
  115.   // Abschlu▀ des 3D Konstruktionsvorganges
  116.   IObject3D * inst = NULL;
  117.   constr->Create(NULL, 0, &inst);
  118.   if (!inst) {
  119.     AfxMessageBox("Konstruktion des 3D-Objektes ist fehlgeschlagen!");
  120.     return;
  121.   }
  122.   inst->put_Flags(AC_3DFL_DBLCLICK | AC_3DFL_CONSTMODE | AC_3DFL_DESIGNMODE | AC_3DFL_SHOWALL);
  123.  
  124.   // Transformati0onsmatrix in ein SafeArray verpacken
  125.   VARIANT v;
  126.   VariantInit(&v);
  127.   v.vt = VT_ARRAY|VT_R4;
  128.   SAFEARRAYBOUND bounds[2];
  129.   bounds[0].lLbound = 0;
  130.   bounds[0].cElements = 4;
  131.   bounds[1].lLbound = 0;
  132.   bounds[1].cElements = 4;
  133.   v.parray = SafeArrayCreate(VT_R4, 2, bounds);
  134.   void *mem = NULL;
  135.   SafeArrayAccessData(v.parray, &mem);
  136.   memcpy(mem, m2w, sizeof m2w);
  137.   SafeArrayUnaccessData(v.parray);
  138.  
  139.   // Transformation setzen
  140.   VARIANT_BOOL ok;
  141.   inst->SetModelToWorldTransformation(v, &ok);
  142.  
  143.   // SafeArray freigeben
  144.   SafeArrayDestroy(v.parray);
  145.  
  146.   // und in die Welt einfⁿgen
  147.   if (intoWorld) {
  148.     // jetzt geh÷rt es ArCon
  149.     inst->InsertIntoWorld(0, &ok);
  150.   } else {
  151.     // Eine Linie als TrΣgerobjekt (man k÷nnte auch ein "Label" als Beschriftung verwenden).
  152.     // Diese Linie mu▀ in einer der Graphics2D Listen eingetragen sein.
  153.     ILine * line;
  154.     m_pArCon->NewLine(AC_LayerLast, &line);
  155.     line->put_Visible(VARIANT_TRUE);
  156.     IGraphics2DCollection *g;
  157.     m_pArCon->get_Graphics2D(&g);
  158.     VARIANT_BOOL ok;
  159.     g->Add(line, &ok);
  160.  
  161.     // Nur wenn ein gⁿltiger Cursor ⁿbergeben wird, erscheint auch der Hinweistext
  162.     inst->SetOutline2D(line, 
  163.                        (long)LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_NICHT_CLICKBAR)), 
  164.                        A2BSTR("Diese Objekt ist nicht doppelklickbar"));
  165.     line->Release();
  166.     g->Release();
  167.   }
  168. }
  169.  
  170. void COEMDlg::CreateOneCube(float x, float y, float z, COLORREF col, const CString &name, BOOL intoWorld)
  171. {
  172.   IObjectConstructor * constr = NULL;
  173.   m_pArCon->NewObjectConstructor(0, TWOPI / 360 * 105, &constr);
  174.  
  175.   IMaterial * mat = NULL;
  176.   m_pArCon->NewMaterial(&mat);
  177.   mat->put_AmbientCoefficient(0.2f);
  178.   mat->put_DiffuseCoefficient(0.4f);
  179.   mat->put_SpecularCoefficient(0.4f);
  180.   mat->put_DiffuseColor(col);
  181.   mat->put_SpecularColor(col);
  182.   mat->put_Transparent(0);
  183.  
  184.   VARIANT v;
  185.   
  186.   static Point contur[6][4] =
  187.   {
  188.     {
  189.       { -0.5f, +0.5f, -0.5f, 0.0f, 1.0f },
  190.       { +0.5f, +0.5f, -0.5f, 1.0f, 1.0f },
  191.       { +0.5f, -0.5f, -0.5f, 1.0f, 0.0f },
  192.       { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f },
  193.     },
  194.     {
  195.       { -0.5f, -0.5f, +0.5f, 0.0f, 0.0f },
  196.       { +0.5f, -0.5f, +0.5f, 1.0f, 0.0f },
  197.       { +0.5f, +0.5f, +0.5f, 1.0f, 1.0f },
  198.       { -0.5f, +0.5f, +0.5f, 0.0f, 1.0f },
  199.     },
  200.     {
  201.       { -0.5f, +0.5f, +0.5f, 0.0f, 1.0f },
  202.       { -0.5f, +0.5f, -0.5f, 1.0f, 1.0f },
  203.       { -0.5f, -0.5f, -0.5f, 1.0f, 0.0f },
  204.       { -0.5f, -0.5f, +0.5f, 0.0f, 0.0f },
  205.     },
  206.     {
  207.       { +0.5f, -0.5f, +0.5f, 0.0f, 0.0f },
  208.       { +0.5f, -0.5f, -0.5f, 1.0f, 0.0f },
  209.       { +0.5f, +0.5f, -0.5f, 1.0f, 1.0f },
  210.       { +0.5f, +0.5f, +0.5f, 0.0f, 1.0f },
  211.     },
  212.     {
  213.       { -0.5f, +0.5f, +0.5f, 0.0f, 0.0f },
  214.       { +0.5f, +0.5f, +0.5f, 1.0f, 0.0f },
  215.       { +0.5f, +0.5f, -0.5f, 1.0f, 1.0f },
  216.       { -0.5f, +0.5f, -0.5f, 0.0f, 1.0f },
  217.     },
  218.     {
  219.       { -0.5f, -0.5f, -0.5f, 0.0f, 1.0f },
  220.       { +0.5f, -0.5f, -0.5f, 1.0f, 1.0f },
  221.       { +0.5f, -0.5f, +0.5f, 1.0f, 0.0f },
  222.       { -0.5f, -0.5f, +0.5f, 0.0f, 0.0f },
  223.     },
  224.   };
  225.   
  226.   for (int i = 0; i < 6; i++) {
  227.     PointsToVariant(contur[i], v);
  228.     constr->SetContur(4, v);
  229.     VariantClear(&v);
  230.     constr->AddQuadriliteral(~0, mat, NULL);
  231.   }
  232.   
  233.   VARIANT_BOOL ok;
  234.   constr->Finish(name.AllocSysString(), 0, ACO_DURATION_CACHEABLE, &ok);
  235.  
  236.   // Konstruktion ist abgeschlossen, in die Welt damit
  237.   InstanceIntoWorld(constr, x, y, z, intoWorld);
  238.  
  239.   // OLE Objekte wieder freigeben
  240.   mat->Release();
  241.   constr->Release();
  242. }
  243.  
  244. /////////////////////////////////////////////////////////////////////////////
  245. // Demo: erzeuge einige Wⁿrfel
  246. void COEMDlg::CreateCubes(float dx, float dy, float dz, BOOL intoWorld)
  247. {  
  248.   int j = 1, i=rand();
  249.  
  250.   for (float x=-10.0f; x<10.5f; x+=4.0f)
  251.     for (float y=-10.0f; y<11.5f; y+=4.0f)
  252.       for (float z=-10.0f; z<11.5f; z+=4.0f) {
  253.         CString name;
  254.         name.Format("Wⁿrfel # %d", j);
  255.         CreateOneCube(dx+x, dy+y, dz+z, RGB(i&1?255:0,i&2?255:0,i&4?255:0), name, intoWorld);
  256.         j++, i++;
  257.       }
  258. }
  259.  
  260. void COEMDlg::AdjustArConWnd(int cx, int cy)
  261. {
  262.     
  263.     HWND parent = ::GetDlgItem(m_hWnd, IDC_ARCON_FRAME);
  264.   if (!parent) return;  // noch nicht soweit, der Dialog wird erst aufgebaut
  265.  
  266.  
  267.   RECT r; POINT plt, prb;
  268.   ::GetWindowRect(parent, &r);
  269.   plt.x = r.left; plt.y = r.top;
  270.   prb.x = r.right; prb.y = r.bottom;
  271.   ::ScreenToClient(m_hWnd, &plt);
  272.   ::ScreenToClient(m_hWnd, &prb);
  273.   ::MoveWindow(parent, plt.x, plt.y, cx-plt.x-5, cy-plt.y-5, TRUE);
  274.   ::GetClientRect(parent, &r);
  275.   ::MoveWindow(m_arconWnd, r.left+1, r.top+1, r.right-1, r.bottom-1, TRUE);
  276.   
  277.   // Wichtig: damit ArCon's interne Verwaltung der Fensterposition funktioniert,
  278.   // mu▀ es hier von seiner PositionsΣnderung informiert werden (als Child-Window
  279.   // bekommt es diese Information nicht von Windows)
  280.   m_pArCon->UpdateWindowPos();
  281. }
  282.  
  283. /////////////////////////////////////////////////////////////////////////////
  284. // COEMDlg message handlers
  285.  
  286. BOOL COEMDlg::OnInitDialog()
  287. {
  288.     CDialog::OnInitDialog();
  289.  
  290.     SetIcon(m_hIcon, TRUE);            // Set big icon
  291.     SetIcon(m_hIcon, FALSE);        // Set small icon
  292.     
  293.   // Erzeuge ein ArCon Server Objekt
  294.     HRESULT res = CoCreateInstance(CLSID_ArCon, NULL, CLSCTX_LOCAL_SERVER, IID_IArCon, (void**)&m_pArCon);
  295.   if (FAILED(res)) {
  296.     TRACE("CoCreateInstance fehlgeschlagen: 0x%x\n", res);
  297.     AfxMessageBox("FATAL: kann ArCon OLE Schnittstelle nicht erreichen,\n"
  298.                   "CoCreateInstance ist fehlgeschlagen!");
  299.     PostQuitMessage(0);
  300.     return TRUE;
  301.   }
  302.  
  303.   ((CButton*)GetDlgItem(IDC_ARCON_VISIBLE))->SetCheck(2);
  304.   ((CButton *)GetDlgItem(IDC_VISIBLE))->SetCheck(2);;
  305.   
  306.   // ArCon-Window in unseren Dialog integrieren
  307.   HWND parent = ::GetDlgItem(m_hWnd, IDC_ARCON_FRAME);
  308.   
  309.   // Starte die ArCon Verbindung mit ArCon als Child
  310.   CString helpFileName(AfxGetApp()->m_pszHelpFilePath);
  311.   VARIANT_BOOL ok;
  312.   m_pArCon->StartMe2((long)m_hWnd, helpFileName.AllocSysString(), TRUE, (long)parent, &ok);
  313.  
  314.   // Ermittle das ArCon Window-Handle
  315.   m_pArCon->get_ArConWindowHandle((long*)&m_arconWnd);
  316.  
  317.   // ArCon richtig positionieren
  318.   CRect r;
  319.   GetClientRect(r);
  320.   AdjustArConWnd(r.right-r.left, r.bottom-r.top);
  321.  
  322. #if 0
  323.   // Alle Menⁿ's und Panels entfernen
  324.   m_pArCon->ShowMenu(AC_NoMode, FALSE, &ok);
  325.   m_pArCon->ShowMenu(AC_ModeConstruct, FALSE, &ok);
  326.   m_pArCon->ShowMenu(AC_ModeDesign, FALSE, &ok);
  327. #endif
  328.  
  329.   // Nur zur Demonstration: nur einen Menⁿpunkt entfernen:
  330.   m_pArCon->RemoveAnyMenuItem(AC_MenuDesign_Datei, &ok);
  331.  
  332.   m_pArCon->ShowPanel(ACBI_UpperPannel|ACBI_ConstructionMode, FALSE, &ok);
  333.   m_pArCon->ShowPanel(ACBI_HowPannel, FALSE, &ok);
  334.   m_pArCon->ShowPanel(ACBI_LeftPannel|ACBI_ConstructionMode, FALSE, &ok);
  335.   m_pArCon->ShowPanel(ACBI_LeftPannel|ACBI_DesignMode, FALSE, &ok);
  336.   m_pArCon->ShowPanel(ACBI_LowerPannel, FALSE, &ok);
  337.   //m_pArCon->ShowPanel(ACBI_ViewPannel, FALSE, &ok);
  338.   // BetrachterStandpunkt, Gescho▀box in Viewleiste ausblenden, IDs stehen in Button-IDs.txt
  339.   m_pArCon->ShowButtonByID(ACBI_ViewPannel, 2576, 0, FALSE, &ok);
  340.   m_pArCon->ShowButtonByID(ACBI_ViewPannel, 2593, 0, FALSE, &ok);
  341.   m_pArCon->ShowButtonByID(ACBI_ViewPannel, 2592, 0, FALSE, &ok);
  342.   //m_pArCon->ShowButtonByID(ACBI_ViewPannel, 2576, 0, FALSE, &ok);
  343.  
  344.   //m_pArCon->ShowPanel(ACBI_StatusPannel, FALSE, &ok);
  345.  
  346.   // Ein neues Projekt erzeugen, falls gerade keines geladen ist
  347.   long mode;
  348.   m_pArCon->get_Mode(&mode);
  349.   if (mode == AC_NoMode) {
  350.     IProject * pPrj = NULL;
  351.     m_pArCon->NewProject(&pPrj);
  352.     m_pArCon->CreateProject(pPrj);
  353.     pPrj->Release();
  354.   }
  355.  
  356.   // In den Designmodus schalten
  357.   m_pArCon->put_Mode(AC_ModeDesign);
  358.  
  359.  
  360.   // OK, jetzt kann ArCon erscheinen
  361.   m_pArCon->put_MultiUserMode(ACMU_DEFAULT);
  362.  
  363.  
  364.     return FALSE;  // wir haben den Focus auf "ArCon" gesetzt
  365. }
  366.  
  367. // If you add a minimize button to your dialog, you will need the code below
  368. //  to draw the icon.  For MFC applications using the document/view model,
  369. //  this is automatically done for you by the framework.
  370.  
  371. void COEMDlg::OnPaint() 
  372. {
  373.     if (IsIconic())
  374.     {
  375.         CPaintDC dc(this); // device context for painting
  376.  
  377.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  378.  
  379.         // Center icon in client rectangle
  380.         int cxIcon = GetSystemMetrics(SM_CXICON);
  381.         int cyIcon = GetSystemMetrics(SM_CYICON);
  382.         CRect rect;
  383.         GetClientRect(&rect);
  384.         int x = (rect.Width() - cxIcon + 1) / 2;
  385.         int y = (rect.Height() - cyIcon + 1) / 2;
  386.  
  387.         // Draw the icon
  388.         dc.DrawIcon(x, y, m_hIcon);
  389.     }
  390.     else
  391.     {
  392.         CDialog::OnPaint();
  393.     }
  394. }
  395.  
  396. HCURSOR COEMDlg::OnQueryDragIcon()
  397. {
  398.     return (HCURSOR) m_hIcon;
  399. }
  400.  
  401. void COEMDlg::OnClose() 
  402. {
  403.   VARIANT_BOOL ok = 0;
  404.   if (m_pArCon) {                             // Verbindung wurde aufgebaut 
  405.     m_pArCon->EndArCon(&ok);                  // ArCon schlie▀en und freigeben
  406.     m_pArCon->Release();
  407.     m_pArCon = NULL;
  408.   }
  409.   
  410.   CDialog::OnClose();
  411. }
  412.  
  413. void COEMDlg::OnSize(UINT nType, int cx, int cy) 
  414. {
  415.     CDialog::OnSize(nType, cx, cy);
  416.  
  417.   if ((nType != SIZE_RESTORED)&&(nType != SIZE_MAXIMIZED)) return;
  418.  
  419.   AdjustArConWnd(cx, cy);
  420. }
  421.  
  422. void COEMDlg::OnButton1() 
  423. {
  424.   DWORD start = GetTickCount();
  425.  
  426.   CButton * check = (CButton *)GetDlgItem(IDC_IN_WORLD);
  427.   BOOL intoWorld = check->GetCheck() == 1;
  428.  
  429.   CWaitCursor hourglass;
  430.   m_pArCon->ShowWaitCursor(VARIANT_TRUE);
  431.  
  432.   // Maximale Geschwindigkeit, keine Bildschirmupdates
  433.   m_pArCon->put_MultiUserMode(0);
  434.   
  435.   // Demo: ein paar Wⁿrfel erzeugen und in die Welt einfⁿgen
  436.   CreateCubes(4.0f*(float)rand()/(float)RAND_MAX, 
  437.               4.0f*(float)rand()/(float)RAND_MAX, 
  438.               4.0f*(float)rand()/(float)RAND_MAX,
  439.               intoWorld);
  440.  
  441.   // Fertig, wieder normaler Anzeigemodus
  442.   m_pArCon->put_MultiUserMode(ACMU_DEFAULT);
  443.  
  444.   m_pArCon->ShowWaitCursor(VARIANT_FALSE);
  445.  
  446.   DWORD end = GetTickCount();
  447.   CString msg;
  448.   msg.Format("Zeit: %lu ms", end - start);
  449.   m_pArCon->SetStatusText(msg.AllocSysString());
  450.  
  451.   // ArCon den Focus geben, damit der nΣchste Klick auf einen Wⁿrfel
  452.   // funktioniert (oder nicht, wenn das nicht gewⁿnscht ist)
  453.   ::SetFocus(m_arconWnd);
  454. }
  455.  
  456. void COEMDlg::OnMove(int x, int y) 
  457. {
  458.     CDialog::OnMove(x, y);
  459.  
  460.   if (m_pArCon)
  461.       m_pArCon->UpdateWindowPos();
  462. }
  463.  
  464. // Demo: alle Namen anzeigen
  465. void COEMDlg::OnButton2() 
  466. {
  467.   CObjectListDlg dlg(this, m_pArCon);
  468.   dlg.DoModal();
  469. }
  470.  
  471. // ArCon anzeigen/verstecken
  472. void COEMDlg::OnArconVisible() 
  473. {
  474.   CButton* btn = (CButton*)GetDlgItem(IDC_ARCON_VISIBLE);
  475.   HWND parent = ::GetDlgItem(m_hWnd, IDC_ARCON_FRAME);
  476.   if (btn->GetCheck() == 0) {
  477.     // ArCon verbergen
  478.     m_pArCon->SetParentWindow(0);
  479.     // Parent (Rahmen) auch ausblenden
  480.     ::ShowWindow(parent, SW_HIDE);
  481.   } else {
  482.     // Parent (Rahmen) wieder anzeigen
  483.     ::ShowWindow(parent, SW_SHOW);
  484.     // ArCon wieder in den Dialog einhΣngen
  485.     m_pArCon->SetParentWindow((long)parent);
  486.     // das (neue) Child-Window richtig positionieren
  487.     CRect r;
  488.     GetClientRect(r);
  489.     AdjustArConWnd(r.right-r.left, r.bottom-r.top);
  490.     // und das fertig positionierte Window anzeigen
  491.     ::ShowWindow(m_arconWnd, SW_SHOW);
  492.   }
  493. }
  494.  
  495. // Alle in die Welt eingefⁿgten Wⁿrfel l÷schen
  496. void COEMDlg::OnButton3() 
  497. {
  498.   long count = 0;
  499.   CButton * check = (CButton *)GetDlgItem(IDC_IN_WORLD);
  500.   BOOL intoWorld = check->GetCheck() == 1;
  501.  
  502.   {
  503.     CWaitCursor hourglass;
  504.     m_pArCon->ShowWaitCursor(VARIANT_TRUE);
  505.     m_pArCon->put_MultiUserMode(0);
  506.  
  507.     if (intoWorld) {
  508.       IObject3DCollection * dieInstanzen;
  509.       IObject3D * derWuerfel;
  510.       long i, num;
  511.  
  512.       m_pArCon->get_DesignObjects(&dieInstanzen);
  513.       dieInstanzen->get_Count(&num);
  514.  
  515.       for (i = num; i > 0; i--) {
  516.         dieInstanzen->Item(i, &derWuerfel);
  517.         VARIANT_BOOL succeded;
  518.         derWuerfel->Delete(VARIANT_TRUE, &succeded);
  519.         if (succeded)
  520.           count++;
  521.         derWuerfel->Release();
  522.       }
  523.       dieInstanzen->Release();
  524.     } else {
  525.       IObjectConstructorCollection * dieObjekte;
  526.       IObject3DCollection * dieInstanzen;
  527.       IObjectConstructor * dasObjekt;
  528.       IObject3D * derWuerfel;
  529.       IGraphics2DCollection * die2DObjekte;
  530.       VARIANT_BOOL succeded;
  531.       long i, num, numInst;
  532.  
  533.       m_pArCon->get_DesignObjectConstructors(&dieObjekte);
  534.       dieObjekte->get_Count(&num);
  535.       for(i=num; i > 0; i--) {
  536.         dieObjekte->Item(i,&dasObjekt);
  537.         dasObjekt->get_Objects(&dieInstanzen);
  538.         dieInstanzen->get_Count(&numInst);
  539.         for(int k = numInst; k > 0; k--) {
  540.           dieInstanzen->Item(k, &derWuerfel);
  541.           derWuerfel->Delete(VARIANT_TRUE, &succeded);
  542.           if (succeded)
  543.             count++;
  544.           derWuerfel->Release();
  545.         }
  546.         dasObjekt->Release();
  547.         dieInstanzen->Release();
  548.       }
  549.       dieObjekte->Release();
  550.  
  551.       m_pArCon->get_Graphics2D(&die2DObjekte);
  552.       die2DObjekte->RemoveAll();
  553.       die2DObjekte->Release();
  554.     }
  555.  
  556.     m_pArCon->put_MultiUserMode(ACMU_DEFAULT);
  557.     m_pArCon->ShowWaitCursor(VARIANT_FALSE);
  558.   }
  559.  
  560.   if (count) {
  561.     CString msg;
  562.     msg.Format("%d Objekte wurden gel÷scht", count);
  563.     AfxMessageBox(msg);
  564.   } else {
  565.     AfxMessageBox("Es konnten keine Objekte gel÷scht werden!");
  566.   }
  567. }
  568.  
  569. void COEMDlg::OnObjectsVisible()
  570. {
  571.   CButton * check = (CButton *)GetDlgItem(IDC_VISIBLE);
  572.   VARIANT_BOOL visible = check->GetCheck() == 1 ? VARIANT_TRUE : VARIANT_FALSE;
  573.   IGraphics2DCollection * die2DObjekte;
  574.   IDispatch * pDisp;
  575.   ILine * dieLinie;
  576.   long i, num;
  577.  
  578.   CWaitCursor hourglass;
  579.   m_pArCon->ShowWaitCursor(VARIANT_TRUE);
  580.   m_pArCon->put_MultiUserMode(0);
  581.   
  582.   m_pArCon->get_Graphics2D(&die2DObjekte);
  583.   die2DObjekte->get_Count(&num);
  584.   for (i = 1; i <= num; i++) {
  585.     // "Aus historischen Grⁿnden" liefert die Graphics2DCollection nur generische
  586.     // Objekte vom Typ IDispatch (die Oberklasse aller ArCon Objekte), nicht die
  587.     // geeignetere Oberklasse aller 2D Grafikobjekte IGraphicsObject. Eine entsprechende
  588.     // ─nderung der Schnittstelle war ohne Bruch der BinΣrkompatibilitΣt nicht mehr
  589.     // m÷glich.
  590.     die2DObjekte->Item(i, &pDisp);
  591.     // Aus dem generischen Objekt holen wir das gewⁿnschte Interface ab - wenn wir 
  592.     // nicht nur Linien erzeugen wⁿrden, mⁿ▀ten wir hier eine Reihe von if / else if 
  593.     // Kaskaden schreiben, bis wir den richtigen Typ erwischen.
  594.     if (FAILED(pDisp->QueryInterface(IID_ILine, (void**)&dieLinie)))
  595.       continue; // das war keine Linie - sollte hier nie passieren
  596.     pDisp->Release(); // das pDisp war nur ein Hilfzeiger auf die Oberklasse, da wir
  597.                       // jetzt die konkrete Klasse haben, brauchen wir ihn nicht mehr
  598.     // Die Sichtbarkeit der Linie Σndern
  599.     dieLinie->put_Visible(visible);
  600.     // Fertig, die Linie brauchen wir nicht mehr
  601.     dieLinie->Release();
  602.   }
  603.   die2DObjekte->Release();
  604.   
  605.   m_pArCon->put_MultiUserMode(ACMU_DEFAULT);
  606.   m_pArCon->ShowWaitCursor(VARIANT_FALSE);
  607. }
  608.