#include /* Needed for message crackers. */ #include /* Required for all Windows applications. */ #include /* Windows' header for common controls. */ #include /* Windows' header for common dialog box. */ #include /* Needed for process control functions. */ #include "..\..\..\include\ltkrn.h" #include "..\..\..\include\ltdic.h" #include "..\..\..\include\ltefx.h" #include "..\..\..\include\ltlck.h" #include "IODDemo.h" /* Application specific header file. */ #include "resource.h" static OPENFILENAME ofn ; #define UIDLEN 64 TCHAR INSTANCEGUID[UIDLEN]; //Generate a UID void CreateGUID() { SYSTEMTIME SystemTime; FILETIME FileTime; DWORD Tick; DWORD HighWord; GetSystemTime(&SystemTime); SystemTimeToFileTime(&SystemTime,&FileTime); Tick=GetTickCount(); HighWord=FileTime.dwHighDateTime+0x146BF4; wsprintf( INSTANCEGUID, TEXT("1.2.840.114257.0.1%010u%05u%05u%05u%05u%05u%05u"), FileTime.dwLowDateTime, LOWORD(HighWord), HIWORD(HighWord |0x10000000), LOWORD(rand()), HIWORD(Tick), LOWORD(Tick), LOWORD(rand())); return ; } HINSTANCE hInst ; //Windows main function int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { L_CHAR szData[MAX_PATH]; L_INT nLength; //Unlock support for medical toolkit UNLOCKSUPPORT (); //Test unlock support for medical toolkit if(L_IsSupportLocked(L_SUPPORT_MEDICAL)) { LoadString(NULL, IDS_ERROR_UNLOCKED_SUPPORT, szData, MAX_PATH); MessageBox(NULL, szData, "Error", MB_OK); return -1; } //Init Windows common controls InitCommonControls(); //Set path to Help file GetCurrentDirectory(MAX_PATH, m_szHelpPath); nLength = strrchr(m_szHelpPath, '\\') - m_szHelpPath; m_szHelpPath[nLength] = '\0'; LoadString(NULL, IDS_HELP_PATH, szData, MAX_PATH); strcat(m_szHelpPath, szData); //Main dialog window return (DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAINDLG), NULL, DlgWndProc)); } //Handling main dialog messages BOOL CALLBACK DlgWndProc (HWND hDlg, L_UINT Message, WPARAM wParam, LPARAM lParam) { L_CHAR strWinDir[MAX_PATH]; L_UINT16 uSize = MAX_PATH; switch (Message) { case WM_INITDIALOG: { //Init default values m_nRows = USER_DEFAULT_ROWS; m_nColumns = USER_DEFAULT_COLUMNS; strcpy(m_szText, USER_DEFAULT_TEXT); //Show the default values for the Overlay Plane Module SetDlgItemText(hDlg, IDC_EDIT_TYPE, "G"); SetDlgItemText(hDlg, IDC_EDIT_ORIGIN, "1/1"); SetDlgItemInt(hDlg, IDC_EDIT_BPOSITION, 0, 0); SetDlgItemInt(hDlg, IDC_EDIT_BALLOCATED, 1, 0); SetDlgItemInt(hDlg, IDC_EDIT_ROWS, m_nRows, 0); SetDlgItemInt(hDlg, IDC_EDIT_COLUMNS, m_nColumns, 0); SetDlgItemText(hDlg, IDC_EDIT_TEXT, m_szText); //Show current step SetDlgItemText(hDlg, IDC_STEP, "1: Delete IOD Class"); m_nStep = 1; Add_IOD_Tree(hDlg, 0, ""); return TRUE; } case WM_CLOSE: { EndDialog(hDlg, TRUE); return TRUE; } case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: { EndDialog(hDlg, TRUE); return TRUE; } case IDC_STEP: { Step_IOD(hDlg); return TRUE; } case IDC_OVERLAY_HELP: { GetWindowsDirectory(strWinDir, uSize); strcat(strWinDir,"\\hh.exe"); _spawnl(_P_NOWAIT,strWinDir,strWinDir,m_szHelpPath, NULL); return TRUE; } } break; } } return FALSE; } //Handling message dialog messages BOOL CALLBACK MessageWndProc (HWND hDlg, L_UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_INITDIALOG: { //Show current message SetDlgItemText(hDlg, IDC_MESSAGE, m_szMessage); return TRUE; } case WM_CLOSE: { EndDialog(hDlg, TRUE); return TRUE; } case WM_COMMAND: { switch(GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: { EndDialog(hDlg, TRUE); return TRUE; } } } } return FALSE; } L_INT Find_Delete_IOD(HWND hDlg) { DICOMIOD *pElementIOD, *pModuleIOD, *pClassIOD; DICOMUID *pElementUID; L_CHAR szData[MAX_PATH]; //Load default IOD structure L_DicomDefaultIOD(); /******************************************************/ /* Show how to find IOD classes, modules and elements */ /* in the LEAD predefined IOD tree structure */ /******************************************************/ // Find the specified class pClassIOD = L_DicomFindClassIOD(USER_CLASS); if (pClassIOD == NULL) { return FALSE; } // Find the specified module inside the class pModuleIOD = L_DicomFindModuleIOD(USER_CLASS, MODULE_OVERLAY_IDENTIFICATION); if (pModuleIOD == NULL) { return FALSE; } LoadString(NULL, IDS_DELETE_IOD_MESSAGE1, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); // Find a specific element inside the module // In order to find the elements from the Module Overlay // Identification you must move the tree cursor to the element level pElementIOD = L_DicomGetChildIOD(pModuleIOD); pElementIOD = L_DicomFindIOD( pElementIOD, TAG_OVERLAY_NUMBER, IOD_TYPE_ELEMENT, TRUE); if (pElementIOD == NULL) { return FALSE; } LoadString(NULL, IDS_DELETE_IOD_MESSAGE2, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); /*********************************************************/ /* Show how to delete IOD classes, modules and elements */ /* in the LEAD predefined IOD tree structure. */ /* Please note that when you delete a class, all modules */ /* under that class get deleted and hence all the */ /* elements under those modules. In the steps below we */ /* delete an element from a module then a module from */ /* the class and then the class itself for illustration */ /* purposes . */ /*********************************************************/ // Delete element Overlay Name L_DicomGetChildIOD(pModuleIOD); // Find the element first pElementIOD = L_DicomFindIOD( pElementIOD, TAG_OVERLAY_NUMBER, IOD_TYPE_ELEMENT, TRUE); if (pElementIOD == NULL) { return FALSE; } // Then delete it L_DicomDeleteIOD(pElementIOD); //Show a message indicating that the element was deleted LoadString(NULL, IDS_DELETE_IOD_MESSAGE3, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); // Delete module Overlay Identification and implicitly all elements from this // module (Overlay Number, Date, Time etc) L_DicomDeleteIOD(pModuleIOD); //Show a message indicating that the Module was deleted LoadString(NULL, IDS_DELETE_IOD_MESSAGE4, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); //Delete class Overlay Storage and implicitly all modules from this class L_DicomDeleteIOD(pClassIOD); //Delete the associate UID from LEAD predefined UID tree structure pElementUID = L_DicomFindUID(USER_CLASS_UID); L_DicomDeleteUID(pElementUID); //Show a message indicating that the Class was deleted LoadString(NULL, IDS_DELETE_IOD_MESSAGE5, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); //All these functions will return errors (pElementIOD = NULL) pElementIOD = L_DicomFindModuleIOD(USER_CLASS, MODULE_OVERLAY_IDENTIFICATION); LoadString(NULL, IDS_DELETE_IOD_MESSAGE6, szData, MAX_PATH); Add_IOD_Tree(hDlg, 0, szData); pElementIOD = L_DicomFindClassIOD(USER_CLASS); LoadString(NULL, IDS_DELETE_IOD_MESSAGE7, szData, MAX_PATH); Add_IOD_Tree(hDlg, 0, szData); pElementUID = L_DicomFindUID(USER_CLASS_UID); return TRUE; } L_INT Add_IOD(HWND hDlg) { DICOMIOD *pElementIOD, *pModuleIOD, *pClassIOD; DICOMUID *pElementUID; CHAR szData[MAX_PATH]; /***************************************************/ /* In order to add a new IOD class we have to add */ /* 1. UID Class in UID LEAD table */ /* 2. IOD Class in IOD LEAD table */ /* 3. IOD Modules to the IOD Class */ /* 4. IOD Elements to the IOD Modules */ /***************************************************/ //Add UID and IOD for the Class pElementUID = L_DicomInsertUID(USER_CLASS_UID, "Standalone Overlay Storage", UID_TYPE_CLASS); if (pElementUID == FALSE) { return FALSE; } // Insert this class to the IOD table pClassIOD = L_DicomInsertIOD( NULL, FALSE, USER_CLASS, "Standalone Overlay Storage", IOD_TYPE_CLASS, 0, USER_CLASS_UID); if (pClassIOD == NULL) { return FALSE; } // Display a message indicating that we succeeded in inserting the class LoadString(NULL, IDS_ADD_IOD_MESSAGE1, szData, MAX_PATH); Add_IOD_Tree(hDlg, 0, szData); //Add IOD Module Overlay Identification pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_OVERLAY_IDENTIFICATION, "Overlay Identification", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } // Display a message indicating that we succeeded in inserting the module LoadString(NULL, IDS_ADD_IOD_MESSAGE2, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); //Add IOD Elements for the module Overlay Identification pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_NUMBER, "Overlay Number", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); LoadString(NULL, IDS_ADD_IOD_MESSAGE3, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); //Add IOD Module Patient pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_PATIENT, "Patient", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } //Add IOD Elements for the module Patient if(AddPatientModuleElements(pModuleIOD) != TRUE) { return FALSE; } //Add IOD Module General Study pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_GENERAL_STUDY, "General Study", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } //Add IOD Elements for the module General Study if(AddGeneralStudyModuleElements(pModuleIOD) != TRUE) { return FALSE; } //Add IOD Module General Series pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_GENERAL_SERIES, "General Series", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } //Add IOD Elements for the module General Series if(AddGeneralSeriesModuleElements(pModuleIOD) != TRUE) { return FALSE; } //Add IOD Module SOP Common pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_SOP_COMMON, "SOP Common", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } //Add IOD Elements for the module SOP Common pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_SOP_INSTANCE_UID, "SOP Instance UID", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); //Add IOD Elements for the module SOP Common pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_SOP_CLASS_UID, "SOP Class UID", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); //Add IOD Module General Equipment pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_GENERAL_EQUIPMENT, "General Equipment", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } //Add IOD Elements for the module General Equipment pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_MANUFACTURER, "Manufacturer", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); //Add IOD Module Overlay Plane pModuleIOD = L_DicomInsertIOD( pClassIOD, TRUE, MODULE_OVERLAY_PLANE, "Overlay Plane", IOD_TYPE_MODULE, IOD_USAGE_M, ""); if (pModuleIOD == NULL) { return FALSE; } //Add IOD Elements for the module Overlay Plane if (AddOverlayPlaneModuleElements(pModuleIOD) != TRUE) { return FALSE; } pElementIOD = L_DicomFindClassIOD(USER_CLASS); LoadString(NULL, IDS_ADD_IOD_MESSAGE4, szData, MAX_PATH); Add_IOD_Tree(hDlg, pModuleIOD, szData); return TRUE; } L_INT Add_IOD_Tree(HWND hDlg, DICOMIOD* pIOD, L_CHAR* szText) { HWND wnd; TVINSERTSTRUCT itemInsert; TVITEM item; DICOMIOD *pElementIOD, *pModuleIOD, *pClassIOD; HTREEITEM hModuleItem, hClassItem, hItemSelected; wnd = GetDlgItem(hDlg, IDC_TREE); //Construct the IOD tree TreeView_DeleteAllItems(wnd); //Find user IOD Class pClassIOD = L_DicomFindClassIOD(USER_CLASS); if (pClassIOD == NULL) { if (szText != "") { strcpy(m_szMessage, szText); DialogBox(NULL, MAKEINTRESOURCE(IDD_MESSAGE), hDlg, MessageWndProc); } return FALSE; } //Insert IOD Class item.mask = TVIF_TEXT; itemInsert.hParent = NULL; itemInsert.hInsertAfter = TVI_LAST; item.pszText = pClassIOD->pszName; itemInsert.item = item; hClassItem = TreeView_InsertItem(wnd, &itemInsert); pModuleIOD = L_DicomGetChildIOD(pClassIOD); while (pModuleIOD != NULL) { if (pModuleIOD->nUsage == IOD_USAGE_M) { //Insert IOD Module item.pszText = pModuleIOD->pszName; itemInsert.hParent = hClassItem; itemInsert.item = item; hModuleItem = TreeView_InsertItem(wnd, &itemInsert); if (pModuleIOD == pIOD) { hItemSelected = hModuleItem; } } pElementIOD = L_DicomGetChildIOD(pModuleIOD); while (pElementIOD != NULL) { //Insert IOD Element type 1, 1C, 2, 2C if ((pElementIOD->nUsage == IOD_USAGE_1) || (pElementIOD->nUsage == IOD_USAGE_1C) || (pElementIOD->nUsage == IOD_USAGE_2) || (pElementIOD->nUsage == IOD_USAGE_2C)) { //Show the type for the specified element //sz.Format(" - Type :%d",pElementIOD->nUsage); //sz = pElementIOD->pszName + sz; if (pElementIOD == pIOD) { item.pszText = pElementIOD->pszName; itemInsert.hParent = hModuleItem; itemInsert.item = item; hItemSelected = TreeView_InsertItem(wnd, &itemInsert); } else { item.pszText = pElementIOD->pszName; itemInsert.hParent = hModuleItem; itemInsert.item = item; TreeView_InsertItem(wnd, &itemInsert); } } //Get next IOD element pElementIOD = L_DicomGetNextIOD(pElementIOD, TRUE); } //Get next IOD module pModuleIOD = L_DicomGetNextIOD(pModuleIOD, TRUE); } TreeView_Expand(wnd, hClassItem, TVE_EXPAND); //Display message if (szText != "") { TreeView_Expand(wnd, hItemSelected, TVE_EXPAND); strcpy(m_szMessage, szText); DialogBox(NULL, MAKEINTRESOURCE(IDD_MESSAGE), hDlg, MessageWndProc); } return TRUE; } L_BOOL AddPatientModuleElements(DICOMIOD *pModuleIOD) { //Add all mandatory elements to the module Patient DICOMIOD *pElementIOD; pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_PATIENT_NAME, "Patient Name", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Patient ID pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_PATIENT_ID, "Patient ID", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Patient Birth Date pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_PATIENT_BIRTH_DATE, "Patient Birth Date", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Patient Sex pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_PATIENT_SEX, "Patient Birth Date", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } return TRUE; } L_BOOL AddGeneralStudyModuleElements(DICOMIOD *pModuleIOD) { //Add all mandatory elements to the module General Study DICOMIOD *pElementIOD; //Insert element Study Instance UID pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_STUDY_INSTANCE_UID, "Study Instance UID", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Study Date pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_STUDY_DATE, "Study Date", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Study Type pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_STUDY_TIME, "Study Time", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Referring Physician Name pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_REFERRING_PHYSICIAN_NAME, "Study Referring Physician Name", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Study ID pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_STUDY_ID, "Study ID", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Accession Number pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_ACCESSION_NUMBER, "Accession Number", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } return TRUE; } L_BOOL AddGeneralSeriesModuleElements(DICOMIOD *pModuleIOD) { //Add all mandatory elements to the module General Series DICOMIOD *pElementIOD; //Insert element Modality pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_MODALITY, "Modality", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Series Instance UID pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_SERIES_INSTANCE_UID, "Series Instance UID", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Series Number pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_SERIES_NUMBER, "Series Number", IOD_TYPE_ELEMENT, IOD_USAGE_2, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Laterality pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_LATERALITY, "Laterality", IOD_TYPE_ELEMENT, IOD_USAGE_2C, ""); if(NULL == pElementIOD) { return FALSE; } //Insert Patient Position pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_PATIENT_POSITION, "Patient Position", IOD_TYPE_ELEMENT, IOD_USAGE_2C, ""); if(NULL == pElementIOD) { return FALSE; } return TRUE; } L_BOOL AddOverlayPlaneModuleElements(DICOMIOD *pModuleIOD) { //Add all mandatory elements to the module Overlay Plane DICOMIOD *pElementIOD; //Insert element Overlay Rows pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_ROWS, "Overlay Rows", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Overlay Columns pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_COLUMNS, "Overlay Columns", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Overlay type pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_TYPE, "Overlay Type", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Overlay Origin pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_ORIGIN, "Overlay Origin", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Overlay Bits Allocated pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_BITS_ALLOCATED, "Overlay Bits Allocated", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Overlay Bit Position pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_BIT_POSITION, "Overlay Bit Position", IOD_TYPE_ELEMENT, IOD_USAGE_1, ""); if(NULL == pElementIOD) { return FALSE; } //Insert element Overlay Data pElementIOD = L_DicomInsertIOD(pModuleIOD, TRUE, TAG_OVERLAY_DATA, "Overlay Data", IOD_TYPE_ELEMENT, IOD_USAGE_1C, ""); if(NULL == pElementIOD) { return FALSE; } return TRUE; } L_BOOL Create_Class() { //Initialize a dataset with our new class m_DS = L_DicomCreateDS(NULL); L_DicomInitDS(m_DS, USER_CLASS, DS_LITTLE_ENDIAN | DS_EXPLICIT_VR); return TRUE; } void PopFileInitialize (HWND hwnd) { } BOOL PopFileSaveDlg ( HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName ) { static TCHAR szFilter[] = TEXT ("Dicom Files (*.DIC)\0*.dic\0") TEXT ("All Files (*.*)\0*.*\0\0") ; ofn.lStructSize = sizeof (OPENFILENAME) ; ofn.hwndOwner = hwnd ; ofn.hInstance = NULL ; ofn.lpstrFilter = szFilter ; ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter = 0 ; ofn.nFilterIndex = 0 ; ofn.nMaxFile = MAX_PATH ; ofn.nMaxFileTitle = MAX_PATH ; ofn.lpstrInitialDir = NULL ; ofn.lpstrTitle = NULL ; ofn.nFileOffset = 0 ; ofn.nFileExtension = 0 ; ofn.lpstrDefExt = TEXT ("txt") ; ofn.lCustData = 0L ; ofn.lpfnHook = NULL ; ofn.lpTemplateName = NULL ; ofn.lpstrFile = pstrFileName ; ofn.lpstrFileTitle = pstrTitleName ; ofn.Flags = OFN_OVERWRITEPROMPT ; return GetSaveFileName (&ofn) ; } L_BOOL Save_Class(HWND hDlg) { /******************************************************/ /* 1. Create a new dataset using our IOD class */ /* 2. Fill in the values for the module Overlay Plane */ /* 3. Save the data set */ /******************************************************/ DICOMELEMENT *pElement; BITMAPHANDLE hBitmap; RECT rct; HGLOBAL hFileInMemory=NULL; L_UINT32 uMemSize; L_INT16 nData; L_INT nRet; HDC m_hDC; static TCHAR szFileName[MAX_PATH], szTitleName[MAX_PATH] ; szFileName[0] = '\0' ; szTitleName[0] = '\0' ; //Set default values for the module //Patient, //General Study, //General Series, //Overlay Identification, //General Equipment AddDefaultValues(); //Set values for the module Overlay Plane elements //Set the element Overlay Bits Allocated nData = GetDlgItemInt(hDlg, IDC_EDIT_BALLOCATED, NULL, TRUE); pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_BITS_ALLOCATED, FALSE); L_DicomSetShortValue(m_DS, pElement, &nData, 1); //Set the element Overlay Bit Position nData = GetDlgItemInt(hDlg, IDC_EDIT_BPOSITION, NULL, TRUE); pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_BIT_POSITION, FALSE); L_DicomSetShortValue(m_DS, pElement, &nData, 1); //Set the element Overlay Origin nData = GetDlgItemInt(hDlg, IDC_EDIT_ORIGIN, NULL, TRUE); pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_ORIGIN, FALSE); L_DicomSetShortValue(m_DS, pElement, &nData, 1); //Set the element Overlay Type pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_TYPE, FALSE); L_DicomSetStringValue(m_DS, pElement, "G", 1); //Set the element Overlay Rows m_nRows = GetDlgItemInt(hDlg, IDC_EDIT_ROWS, NULL, TRUE); pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_ROWS, FALSE); L_DicomSetShortValue(m_DS, pElement, &m_nRows, 1); //Set the element Overlay Columns m_nColumns = GetDlgItemInt(hDlg, IDC_EDIT_COLUMNS, NULL, TRUE); pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_COLUMNS, FALSE); L_DicomSetShortValue(m_DS, pElement, &m_nColumns, 1); GetDlgItemText(hDlg, IDC_EDIT_TEXT, m_szText, 128); //Create Overlay Data in memory nRet = L_CreateBitmap( &hBitmap,sizeof(BITMAPHANDLE), TYPE_CONV, m_nColumns, m_nRows, 24, ORDER_BGR, NULL, TOP_LEFT, NULL, 0); if (nRet != SUCCESS) { TCHAR szErrMsg [64] ; LoadString(hInst, IDS_ERROR_BITMAP, (char *) szErrMsg, sizeof (szErrMsg)) ; MessageBox(hDlg, szErrMsg, "Error", MB_OK); return FALSE; } rct.left = 0; rct.top = 0; rct.right = m_nColumns; rct.bottom = m_nRows; //Create memory contex for Overlay Data m_hDC = L_CreateLeadDC(&hBitmap); if (m_hDC == NULL) { TCHAR szErrMsg [64] ; LoadString(hInst, IDS_ERROR_LEADDC, (char *) szErrMsg, sizeof (szErrMsg)) ; L_FreeBitmap(&hBitmap); MessageBox(hDlg, szErrMsg, "Error", MB_OK); return FALSE; } //Write text to Overlay Data L_EfxDraw3dText(m_hDC, (L_CHAR*)(LPCTSTR)m_szText, &rct, EFX_TEXT_NORMAL, 0, 0, RGB ( 255,255,255 ), RGB ( 0,0,0 ), RGB ( 0,0,0 ), (HFONT) GetStockObject(SYSTEM_FONT ), NULL); //Save Overlay Data to memory nRet = L_SaveBitmapMemory(&hFileInMemory, &hBitmap, FILE_RAW, 1, 0, &uMemSize, NULL); if (nRet != SUCCESS) { TCHAR szErrMsg [64] ; LoadString(hInst, IDS_ERROR_BITMAP, (char *) szErrMsg, sizeof (szErrMsg)) ; L_FreeBitmap(&hBitmap); L_DeleteLeadDC(m_hDC); MessageBox(hDlg, szErrMsg, "Error", MB_OK); return FALSE; } //Set the element Overlay Data pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_DATA, FALSE); L_DicomSetBinaryValue(m_DS, pElement, hFileInMemory, uMemSize); if (PopFileSaveDlg (hDlg, szFileName, szTitleName)) { L_DicomSaveDS(m_DS, szFileName, 0); } //Free resource used L_FreeBitmap(&hBitmap); L_DeleteLeadDC(m_hDC); GlobalFree(hFileInMemory); L_DicomFreeDS(m_DS); return TRUE; } L_VOID Step_IOD(HWND hDlg) { L_INT nRet; RECT rct; HWND wnd; L_INT x, y; POINT point; CHAR szData[MAX_PATH]; switch (m_nStep) { case 1: { //Step 1 //Call function for step 1 nRet = Find_Delete_IOD(hDlg); if (nRet == TRUE) { //Set the controls for step 1 wnd = GetDlgItem(hDlg, IDC_MESSAGE_STEP2); //Move the Group box to the correct position GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; y = rct.top - 10; x = rct.left - 5; wnd = GetDlgItem(hDlg, IDC_RCT); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; OffsetRect(&rct, x - rct.left, y - rct.top); MoveWindow(wnd, rct.left, rct.top, (rct.right - rct.left), (rct.bottom - rct.top), TRUE); SetDlgItemText(hDlg, IDC_STEP, "2: Add IOD Class"); m_nStep++; InvalidateRect(hDlg, NULL, TRUE); } else { LoadString(NULL, IDS_ERROR_DELETE_IOD, szData, MAX_PATH); MessageBox(hDlg, szData, "Error", MB_OK); } break; } case 2: { //Step 2 //Call function for step 2 nRet = Add_IOD(hDlg); if (nRet == TRUE) { //Set the controls for step 2 SetDlgItemText(hDlg, IDC_STEP, "3: Create DICOM"); //Move the Group box to the correct position wnd = GetDlgItem(hDlg, IDC_MESSAGE_STEP3); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; y = rct.top - 10; x = rct.left - 5; wnd = GetDlgItem(hDlg, IDC_RCT); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; OffsetRect(&rct, x - rct.left, y - rct.top); MoveWindow(wnd, rct.left, rct.top, (rct.right - rct.left), (rct.bottom - rct.top), TRUE); m_nStep++; InvalidateRect(hDlg, NULL, TRUE); } else { LoadString(NULL, IDS_ERROR_ADD_IOD, szData, MAX_PATH); MessageBox(hDlg, szData, "Error", MB_OK); } break; } case 3: { //Step 3 //Call function for step 3 nRet = Create_Class(hDlg); if (nRet == TRUE) { //Set the controls for step 3 wnd = GetDlgItem(hDlg, IDC_EDIT_ROWS); SendMessage(wnd, EM_SETREADONLY, FALSE, 0); wnd = GetDlgItem(hDlg, IDC_EDIT_COLUMNS); SendMessage(wnd, EM_SETREADONLY, FALSE, 0); wnd = GetDlgItem(hDlg, IDC_EDIT_TEXT); SendMessage(wnd, EM_SETREADONLY, FALSE, 0); //Move the Group box to the correct position wnd = GetDlgItem(hDlg, IDC_MESSAGE_STEP4); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; y = rct.top - 10; x = rct.left - 5; wnd = GetDlgItem(hDlg, IDC_RCT); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; OffsetRect(&rct, x - rct.left, y - rct.top); MoveWindow(wnd, rct.left, rct.top, (rct.right - rct.left), (rct.bottom - rct.top), TRUE); SetDlgItemText(hDlg, IDC_STEP, "4: Save DICOM"); m_nStep++; InvalidateRect(hDlg, NULL, TRUE); } else { LoadString(NULL, IDS_ERROR_CREATE_DICOM, szData, MAX_PATH); MessageBox(hDlg, szData, "Error", MB_OK); } break; } case 4: { //Step 4 //Call function for step 4 nRet = Save_Class(hDlg); if (nRet == TRUE) { //Set the controls for step 4 wnd = GetDlgItem(hDlg, IDC_EDIT_ROWS); SendMessage(wnd, EM_SETREADONLY, TRUE, 0); wnd = GetDlgItem(hDlg, IDC_EDIT_COLUMNS); SendMessage(wnd, EM_SETREADONLY, TRUE, 0); wnd = GetDlgItem(hDlg, IDC_EDIT_TEXT); SendMessage(wnd, EM_SETREADONLY, TRUE, 0); SetDlgItemText(hDlg, IDC_STEP, "1: Delete IOD Class"); //Move the Group box to the correct position wnd = GetDlgItem(hDlg, IDC_MESSAGE_STEP1); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; y = rct.top - 10; x = rct.left - 5; wnd = GetDlgItem(hDlg, IDC_RCT); GetWindowRect(wnd, &rct); point.x = rct.left; point.y = rct.top; ScreenToClient(hDlg, &point); rct.left = point.x; rct.top = point.y; point.x = rct.right; point.y = rct.bottom; ScreenToClient(hDlg, &point); rct.right = point.x; rct.bottom = point.y; OffsetRect(&rct, x - rct.left, y - rct.top); MoveWindow(wnd, rct.left, rct.top, (rct.right - rct.left), (rct.bottom - rct.top), TRUE); InvalidateRect(hDlg, NULL, TRUE); m_nStep = 1; } else { LoadString(NULL, IDS_ERROR_SAVE_DICOM, szData, MAX_PATH); MessageBox(hDlg, szData, "Error", MB_OK); } break; } } } //Add default values for elements L_VOID AddDefaultValues() { //Set default values DICOMELEMENT *pElement; VALUEDATE dateValue; VALUETIME timeValue; //Set default value for the element Patient Name pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_PATIENT_NAME, FALSE); L_DicomSetStringValue(m_DS, pElement, "John Doe", 1); //Set default value for the element Patient ID pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_PATIENT_ID, FALSE); L_DicomSetStringValue(m_DS, pElement, "ID", 1); //Set default value for the element Patient Birth Date dateValue.nYear = 1900; dateValue.nMonth = 10; dateValue.nDay = 25; pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_PATIENT_BIRTH_DATE, FALSE); L_DicomSetDateValue(m_DS, pElement, &dateValue, 1); //Set default value for the element Patient Sex pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_PATIENT_SEX, FALSE); L_DicomSetStringValue(m_DS, pElement, "M", 1); //Set default value for the element Accession Number pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_ACCESSION_NUMBER, FALSE); L_DicomSetStringValue(m_DS, pElement, "234", 1); //Set default value for the element Referring Physician Name pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_REFERRING_PHYSICIAN_NAME, FALSE); L_DicomSetStringValue(m_DS, pElement, "John Doe", 1); //Set default value for the element Study Date dateValue.nYear = 1999; dateValue.nMonth = 4; dateValue.nDay = 15; pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_STUDY_DATE, FALSE); L_DicomSetDateValue(m_DS, pElement, &dateValue, 1); //Set default value for the element Study ID pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_STUDY_ID, FALSE); L_DicomSetStringValue(m_DS, pElement, "Study 1", 1); //Set default value for the element Study Instance UID pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_STUDY_INSTANCE_UID, FALSE); CreateGUID(); L_DicomSetStringValue(m_DS, pElement, INSTANCEGUID, 1); //Set default value for the element Study Time timeValue.nHours = 0; timeValue.nMinutes = 0; timeValue.nSeconds = 0; timeValue.nFractions = 0; pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_STUDY_TIME, FALSE); L_DicomSetTimeValue(m_DS, pElement, &timeValue, 1); //Set default value for the element Laterality pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_LATERALITY, FALSE); L_DicomSetStringValue(m_DS, pElement, "R", 1); //Set default value for the element Patient Position pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_PATIENT_POSITION, FALSE); L_DicomSetStringValue(m_DS, pElement, "HFP", 1); //Set default value for the element Series Instance UID pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_SERIES_INSTANCE_UID, FALSE); CreateGUID(); L_DicomSetStringValue(m_DS, pElement, INSTANCEGUID, 1); //Set default value for the element Series Number pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_SERIES_NUMBER, FALSE); L_DicomSetConvertValue(m_DS, pElement, "1", 1); //Set default value for the element Manufacturer pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_MANUFACTURER, FALSE); L_DicomSetStringValue(m_DS, pElement, "Brand Name", 1); //Set default value for the element Overlay Number pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_OVERLAY_NUMBER, FALSE); L_DicomSetConvertValue(m_DS, pElement, "1", 1); //Set default value for the element Overlay Number pElement = L_DicomFindFirstElement(m_DS, NULL, TAG_SOP_INSTANCE_UID, FALSE); CreateGUID(); L_DicomSetConvertValue(m_DS, pElement, INSTANCEGUID, 1); }