// MainDlg.cpp : implementation file // #include "stdafx.h" #include "DDir.h" #include "MainDlg.h" #include "..\..\..\..\Include\l_com.h" #include "LRaster.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define GETGROUP(nTag) ((unsigned short)(nTag >> 16)) #define GETELEMENT(nTag) ((unsigned short)(nTag & 0xFFFF)) ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDicomDirSink Class #include CComModule _Module; #include // Type info for the DicomFileInsert event handler function _ATL_FUNC_INFO OnDicomFileInsertInfo = { CC_STDCALL, VT_EMPTY, 4, { VT_BSTR, VT_I4, VT_I2, VT_BYREF | VT_I2 } }; class CDicomDirSink : public IDispEventSimpleImpl<1, CDicomDirSink, &DIID__ILEADDicomDirEvents> { private: ILEADDicomDir* m_pDicomDir; BOOL m_bDicomDirExists; UINT m_uAddedDicomFilesCount; CMainDlg* m_pMainDlg; public: CDicomDirSink(ILEADDicomDir* pDicomDir) { m_bDicomDirExists = FALSE; m_uAddedDicomFilesCount = 0; m_pMainDlg = NULL; m_pDicomDir = pDicomDir; m_pDicomDir->AddRef(); DispEventAdvise((IUnknown*) m_pDicomDir); // Attach to the source } virtual ~CDicomDirSink() { m_pDicomDir->Release(); DispEventUnadvise((IUnknown*) m_pDicomDir); // Detach from the source } VOID __stdcall OnDicomFileInsert(BSTR bstrFileName, LONG hDicomDS, SHORT nStatus, SHORT* pReturnVal); VOID Reset(); VOID SetMainDlg(CMainDlg* pMainDlg); UINT GetAddedDicomFilesCount() const; BOOL DoesDicomDirExist() const; // Note: The DISPID of the DicomFileInsert event is 1 BEGIN_SINK_MAP(CDicomDirSink) SINK_ENTRY_INFO(1, DIID__ILEADDicomDirEvents, 1, OnDicomFileInsert, &OnDicomFileInsertInfo) END_SINK_MAP() }; VOID CDicomDirSink::Reset() { m_bDicomDirExists = FALSE; m_uAddedDicomFilesCount = 0; } VOID CDicomDirSink::SetMainDlg(CMainDlg* pMainDlg) { m_pMainDlg = pMainDlg; } UINT CDicomDirSink::GetAddedDicomFilesCount() const { return m_uAddedDicomFilesCount; } BOOL CDicomDirSink::DoesDicomDirExist() const { return m_bDicomDirExists; } VOID __stdcall CDicomDirSink::OnDicomFileInsert(BSTR bstrFileName, LONG hDicomDS, SHORT nStatus, SHORT* pReturnVal) { if (nStatus == DICOMDIR_INSERTDICOMFILE_PREADD) // About to add the DICOM file? { if (m_pMainDlg) { m_pMainDlg->m_spDicomDS1->hDicomDS = hDicomDS; m_pMainDlg->m_spDicomDS1->GetInfoDS(); m_pMainDlg->m_spDicomDS1->hDicomDS = 0; // Is it a DICOMDIR file? if (m_pMainDlg->m_spDicomDS1->GetInfoClass() == LTDicDSLib::DICOM_CLASS_BASIC_DIRECTORY) { m_bDicomDirExists = TRUE; *pReturnVal = DICOM_ERROR_FORMAT; } else { CString sStatus = "Status: Adding the file \""; sStatus += bstrFileName; sStatus += "\""; m_pMainDlg->SetDlgItemText(IDC_STATUS, sStatus); } } } else if (nStatus == DICOM_SUCCESS) // The DICOM file has been added successfully? { m_uAddedDicomFilesCount++; } } ///////////////////////////////////////////////////////////////////////////// // CMainDlg dialog CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/) : CDialog(CMainDlg::IDD, pParent) { //{{AFX_DATA_INIT(CMainDlg) m_bInsertIconImgSeq = FALSE; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CMainDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMainDlg) DDX_Control(pDX, IDC_TREE, m_Tree); DDX_Control(pDX, IDC_LIST, m_List); DDX_Check(pDX, IDC_CHECK_INSERTICONIMGSEQ, m_bInsertIconImgSeq); DDX_Control(pDX, IDC_LEADRASTERVIEW, m_LeadRasterViewCtrl); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CMainDlg, CDialog) //{{AFX_MSG_MAP(CMainDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse) ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelChangedTree) ON_NOTIFY(TVN_ITEMEXPANDING, IDC_TREE, OnItemExpandingTree) ON_NOTIFY(NM_DBLCLK, IDC_TREE, OnDblClkTree) ON_WM_CLOSE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMainDlg message handlers UINT CMainDlg::m_BitmapList[] = { IDB_STORAGE_EXPANDED, IDB_STORAGE_COLLAPSED, IDB_STREAM }; BOOL CMainDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_LeadRasterViewCtrl.SetEnableMethodErrors(FALSE); m_LeadRasterViewCtrl.SetPaintSizeMode(PAINTSIZEMODE_FIT); m_LeadRasterViewCtrl.SetCenterImage(TRUE); m_LeadRasterViewCtrl.GetRaster().SetRefBitmap(TRUE); UNLOCKSUPPORT(m_LeadRasterViewCtrl.GetRaster()); if (m_LeadRasterViewCtrl.GetRaster().IsSupportLocked(L_SUPPORT_MEDICAL)) { AfxMessageBox("Medical-Express Support must be unlocked for this demo!"); EndDialog(-1); } LPCSTR pszLic = "LEADTOOLS OCX Copyright (c) 1991-2004 LEAD Technologies, Inc."; ILEADDicomFactoryPtr spDicomFactory(__uuidof(LEADDicomFactory)); m_spDicomDS = spDicomFactory->CreateObject2("LEADDicomDS.LEADDicomDS", pszLic); m_spDicomDS->EnableMethodErrors = VARIANT_FALSE; m_spDicomDS1 = spDicomFactory->CreateObject2("LEADDicomDS.LEADDicomDS", pszLic); m_spDicomDS1->EnableMethodErrors = VARIANT_FALSE; spDicomFactory = NULL; CBitmap Bitmap; int iSize = sizeof(m_BitmapList) / sizeof(m_BitmapList[0]); m_ImageList.Create(16, 16, ILC_MASK, 0, iSize); for (int i = 0; i < iSize; i++) { Bitmap.LoadBitmap(m_BitmapList[i]); m_ImageList.Add(&Bitmap, (COLORREF) 0xFFFFFF); Bitmap.DeleteObject(); } m_Tree.SetImageList(&m_ImageList, TVSIL_NORMAL); return TRUE; // return TRUE unless you set the focus to a control } void CMainDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CMainDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CMainDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CMainDlg::OnButtonBrowse() { // Let the user choose a folder if (!GetFolder("Choose a Folder:", m_hWnd)) return; CWaitCursor Wait; m_LeadRasterViewCtrl.GetRaster().SetBitmap(0); m_LeadRasterViewCtrl.ShowWindow(SW_HIDE); m_List.DeleteAllItems(); m_List.ShowWindow(SW_SHOW); m_List.RedrawWindow(); m_Tree.DeleteAllItems(); m_spDicomDS->hDicomDS = 0; SetDlgItemText(IDC_SELECTED_DIR, m_sDicomFilesFolder); ILEADDicomDirPtr spDicomDir(__uuidof(LEADDicomDir)); // Reset the DICOM Directory and set the destination folder where the DICOMDIR // File will be saved spDicomDir->ResetDicomDir(LPCTSTR(m_sDicomFilesFolder)); // The sink CDicomDirSink DicomDirSink(spDicomDir); DicomDirSink.SetMainDlg(this); // If it is desired to change the values of the Implementation Class // UID (0002,0012) and the Implementation Version Name (0002,0013)... spDicomDir->ImplementationClassUID = "1.2.840.114257.0.1"; // Must be a UID spDicomDir->ImplementationVersionName = "LEADTOOLS 13"; // Up to 16 characters // Ensure that subfolders are to be included spDicomDir->IncludeSubfolders = VARIANT_TRUE; // Do we need to insert icon image sequences? UpdateData(TRUE); spDicomDir->InsertIconImageSequence = m_bInsertIconImgSeq ? VARIANT_TRUE : VARIANT_FALSE; // Add the DICOM files (in the folder m_sDicomFilesFolder and all subfolders) to the DICOM // Directory. // The DicomFileInsert event can be used to give the user feedback about the progress of // this method. if (spDicomDir->InsertDicomFile("") != DICOM_SUCCESS) { SetDlgItemText(IDC_STATUS, "Status: Failed to create the DICOM Directory!"); return; } if (DicomDirSink.GetAddedDicomFilesCount() == 0) { SetDlgItemText(IDC_STATUS, "Status: Search is complete. No DICOM files were added to the DICOM Directory."); return; } m_spDicomDS->ResetDS(); m_spDicomDS->hDicomDS = spDicomDir->hDicomDirDS; FillTree(TVI_ROOT, TRUE); CString sStatus; if (DicomDirSink.DoesDicomDirExist()) { int iRet = AfxMessageBox("A DICOMDIR file already exists. Do you want to overwrite it?", MB_YESNO | MB_ICONQUESTION); if (iRet == IDNO) { sStatus.Format("Status: Search is complete. %u file(s) were added to the DICOM " \ "Directory.", DicomDirSink.GetAddedDicomFilesCount()); SetDlgItemText(IDC_STATUS, sStatus); return; } } // Save the DICOMDIR file short nRet = spDicomDir->SaveDicomDir(); if (nRet == DICOM_SUCCESS) { sStatus.Format("Status: Search is complete. %u file(s) were added to the DICOM " \ "Directory. The DICOMDIR file was saved into \"%s\".", DicomDirSink.GetAddedDicomFilesCount(), m_sDicomFilesFolder + "\\DICOMDIR"); SetDlgItemText(IDC_STATUS, sStatus); } else { sStatus.Format("Status: Search is complete. %u file(s) were added to the DICOM " \ "Directory. Failed to save the DICOMDIR file (Error code: %i).", DicomDirSink.GetAddedDicomFilesCount(), nRet); SetDlgItemText(IDC_STATUS, sStatus); } } BOOL CMainDlg::GetFolder(LPCTSTR pszTitle, HWND hWndOwner) { BROWSEINFOA bi; bi.hwndOwner = hWndOwner; bi.pidlRoot = NULL; bi.pszDisplayName = NULL; bi.lpszTitle = pszTitle; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = NULL; bi.lParam = 0; bi.iImage = 0; LPITEMIDLIST pIDL = SHBrowseForFolder(&bi); if (pIDL == NULL) return FALSE; CHAR pszDisplayName[MAX_PATH]; if (SHGetPathFromIDList(pIDL, pszDisplayName)) { m_sDicomFilesFolder = pszDisplayName; return TRUE; } return FALSE; } VOID CMainDlg::FillTree(HTREEITEM hParentTreeItem, BOOL bStarting) { LTDicDSLib::IDicomDSElementPtr spElement; HTREEITEM hItem; short nRet = DICOM_SUCCESS; if (bStarting) { nRet = m_spDicomDS->MoveFirstKey(VARIANT_FALSE); } while (nRet == DICOM_SUCCESS) { hItem = m_Tree.InsertItem(m_spDicomDS->GetKeyValue(), GetTreeItemImage(IDB_STORAGE_COLLAPSED), GetTreeItemImage(IDB_STORAGE_COLLAPSED), hParentTreeItem, TVI_SORT); spElement = m_spDicomDS->GetCurrentElement(); FillSubTree(hItem); m_spDicomDS->SetCurrentElement(spElement->hElement); if (spElement->Length == LTDicDSLib::ELEMENT_LENGTH_MAX) { if (m_spDicomDS->MoveChildKey() == DICOM_SUCCESS) FillTree(hItem); m_spDicomDS->SetCurrentElement(spElement->hElement); } nRet = m_spDicomDS->MoveNextKey(VARIANT_TRUE); } } VOID CMainDlg::FillSubTree(HTREEITEM hParentTreeItem) { HTREEITEM hItem; CString sElement; short nRet; long lTag; nRet = m_spDicomDS->MoveChildElement(); while (nRet == DICOM_SUCCESS) { lTag = m_spDicomDS->GetCurrentElement()->Tag; nRet = m_spDicomDS->FindTag(lTag); sElement.Format("%04X:%04X - %s", GETGROUP(lTag), GETELEMENT(lTag), (nRet == DICOM_SUCCESS) ? LPCSTR(m_spDicomDS->GetCurrentTag()->Name) : "Unknown"); hItem = m_Tree.InsertItem(sElement, GetTreeItemImage(IDB_STREAM), GetTreeItemImage(IDB_STREAM), hParentTreeItem, TVI_SORT); if (hItem) m_Tree.SetItemData(hItem, (DWORD) m_spDicomDS->GetCurrentElement()->hElement); nRet = m_spDicomDS->MoveNextElement(VARIANT_TRUE); } } INT CMainDlg::GetTreeItemImage(UINT uBitmap) { int iSize = sizeof(m_BitmapList) / sizeof(m_BitmapList[0]); for (int iImageIndex = 0; iImageIndex < iSize; iImageIndex++) if (m_BitmapList[iImageIndex] == uBitmap) break; return iImageIndex; } void CMainDlg::OnSelChangedTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*) pNMHDR; if (pNMTreeView->itemNew.hItem != pNMTreeView->itemOld.hItem) { m_LeadRasterViewCtrl.GetRaster().SetBitmap(0); m_LeadRasterViewCtrl.ShowWindow(SW_HIDE); DisplayElementValue(pNMTreeView->itemNew.hItem); } *pResult = 0; } VOID CMainDlg::DisplayElementValue(HTREEITEM hItem) { m_List.DeleteAllItems(); m_List.ShowWindow(SW_SHOW); m_List.RedrawWindow(); if (hItem == NULL) return; long hElement = m_Tree.GetItemData(hItem); if (hElement == 0) return; m_spDicomDS->SetCurrentElement(hElement); m_spDicomDS->GetConvertValue(); long nValuesCount = m_spDicomDS->GetStringValueCount(); for (long i = 0; i < nValuesCount; i++) { m_List.InsertItem(m_spDicomDS->GetStringValues(i)); } m_spDicomDS->StringValueCount = 0; m_List.RedrawWindow(); m_List.SelectItem(m_List.GetFirstVisibleItem()); } void CMainDlg::OnItemExpandingTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*) pNMHDR; UINT uBitmap; if ((pNMTreeView->itemNew.state & TVIS_EXPANDED) != TVIS_EXPANDED) { uBitmap = IDB_STORAGE_EXPANDED; } else { uBitmap = IDB_STORAGE_COLLAPSED; } m_Tree.SetItemImage(pNMTreeView->itemNew.hItem, GetTreeItemImage(uBitmap), GetTreeItemImage(uBitmap)); *pResult = 0; } void CMainDlg::OnDblClkTree(NMHDR* pNMHDR, LRESULT* pResult) { CPoint Point; ::GetCursorPos(&Point); m_Tree.ScreenToClient(&Point); UINT uIndent = m_Tree.GetIndent(); if (Point.x < (long) uIndent) return; HTREEITEM hItem = m_Tree.HitTest(Point); DisplayImage(hItem); *pResult = 0; } VOID CMainDlg::DisplayImage(HTREEITEM hItem) { if (hItem == NULL) return; long hElement = m_Tree.GetItemData(hItem); if (hElement == 0) return; m_spDicomDS->SetCurrentElement(hElement); if (m_spDicomDS->GetCurrentElement()->Tag != LTDicDSLib::TAG_REFERENCED_FILE_ID) return; CString sFile = m_sDicomFilesFolder; m_spDicomDS->GetConvertValue(); long nValuesCount = m_spDicomDS->GetStringValueCount(); for (long i = 0; i < nValuesCount; i++) { sFile += "\\"; sFile += m_spDicomDS->GetStringValues(i); } m_spDicomDS->StringValueCount = 0; // Load the Data Set in the file if (m_spDicomDS1->LoadDS(LPCSTR(sFile), 0) != DICOM_SUCCESS) { SetDlgItemText(IDC_STATUS, "Status: Failed to load the Data Set."); return; } if (m_spDicomDS1->GetBitmapValue(0, 0, LTDicDSLib::ORDER_RGB, LTDicDSLib::DICOM_GETIMAGE_AUTO_APPLY_MODALITY_LUT| LTDicDSLib::DICOM_GETIMAGE_AUTO_APPLY_VOI_LUT| LTDicDSLib::DICOM_GETIMAGE_ALLOW_RANGE_EXPANSION) == DICOM_SUCCESS) { m_List.ShowWindow(SW_HIDE); m_LeadRasterViewCtrl.ShowWindow(SW_SHOW); m_LeadRasterViewCtrl.GetRaster().SetBitmap(m_spDicomDS1->GetBitmap()); } m_spDicomDS1->hDicomDS = 0; } // This is a trick, so that when the user presses the "Esc" button, our dialog doesn't get // closed. We do nothing inside OnCancel() and we call CDialog::OnCancel() inside OnClose(). void CMainDlg::OnCancel() { } void CMainDlg::OnClose() { CDialog::OnCancel(); }