www.pudn.com > Ì廿֯Âë.rar > volvis.cpp, change:2001-12-11,size:29790b


// volvis.cpp : Definiert den Einsprungpunkt für die Anwendung. 
// 
 
#include <stdio.h> 
#include <math.h> 
#include "stdafx.h" 
#include "resource.h" 
 
#include "openglsupport.h" 
#include "volume.h" 
#include "ray.h" 
#include "raycaster.h" 
#include "transfunc.h" 
#include "transfuncwin.h" 
#include "slicer.h" 
#include "tfvolume.h" 
 
#define MAX_LOADSTRING 100 
 
// definitionen 
 
enum eviewmode {VM_NONE, VM_SLICE, VM_OVERVIEW, VM_VOLUME}; 
enum erendermode {RM_NONE, RM_THRESHOLD, RM_MAXINTENSITY, RM_TRANSPARENCY}; 
 
// Globale Variablen: 
HINSTANCE hInst;					// aktuelle Instanz 
HWND MainWnd = 0; 
TCHAR szTitle[MAX_LOADSTRING];								// Text der Titelzeile 
TCHAR szWindowClass[MAX_LOADSTRING];								// Text der Titelzeile 
 
// Vorausdeklarationen von Funktionen, die in diesem Code-Modul enthalten sind: 
ATOM MyRegisterClass(HINSTANCE hInstance); 
BOOL InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); 
LRESULT CALLBACK TransferFunctionDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); 
LRESULT CALLBACK ParameterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); 
 
// programmspezifische variablen 
 
HWND ParamWnd = 0; 
HWND GLWnd = 0; 
HBITMAP hBmpVolvis = 0; 
Volume *Vol = NULL; 
GLWindow *GLWin = NULL; 
eviewmode viewmode = VM_SLICE; 
erendermode rendermode = RM_THRESHOLD; 
TransferFunction *TransFunc; 
TransferFunctionWindow *TransFuncWin; 
RayCaster *RayCast; 
Slicer *SliceViewer; 
TransferFunctionVolume *TransFuncVol; 
 
//------------------------------------------------------------------------------- 
 
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{ 
	MSG msg; 
	HACCEL hAccelTable; 
 
	// Globale Zeichenfolgen initialisieren 
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
	LoadString(hInstance, IDC_VOLVIS, szWindowClass, MAX_LOADSTRING); 
	MyRegisterClass(hInstance); 
 
	// Initialisierung der Anwendung durchführen: 
	if(!InitInstance(hInstance, nCmdShow)) return FALSE; 
 
	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_VOLVIS)); 
 
	hBmpVolvis = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_VOLVIS)); 
 
	// Hauptnachrichtenschleife: 
	while(GetMessage(&msg, NULL, 0, 0))  
	{ 
		if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))  
		{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		} 
	} 
 
	return msg.wParam; 
} 
 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
	WNDCLASSEX wcex; 
	wcex.cbSize				= sizeof(WNDCLASSEX);  
	wcex.style				= 0; //CS_HREDRAW | CS_VREDRAW; 
	wcex.lpfnWndProc		= (WNDPROC)WndProc; 
	wcex.cbClsExtra		= 0; 
	wcex.cbWndExtra		= 0; 
	wcex.hInstance			= hInstance; 
	wcex.hIcon				= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VOLVIS)); 
	wcex.hCursor			= LoadCursor(NULL, IDC_ARROW); 
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1); 
	wcex.lpszMenuName		= MAKEINTRESOURCE(IDC_VOLVIS); 
	wcex.lpszClassName	= szWindowClass; 
	wcex.hIconSm			= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); 
	return RegisterClassEx(&wcex); 
} 
 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
   HWND hWnd; 
   hInst = hInstance; // Instanzzugriffsnummer in unserer globalen Variable speichern 
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, 
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 
   if(!hWnd) return FALSE; 
   ShowWindow(hWnd, nCmdShow); 
   UpdateWindow(hWnd); 
	InvalidateRgn(hWnd, NULL, TRUE); 
   MainWnd = hWnd; 
   return TRUE; 
} 
 
// ===== Helper Functions ============================================================ 
 
void DrawSlice() 
{ 
   SliceViewer->glDrawSlice(); 
	GLWin->Swap(); 
} 
 
void DrawSlice(int pos) 
{ 
   int threshold = SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_GETPOS, 0, 0); 
   bool usetf = (IsDlgButtonChecked(ParamWnd, IDC_CHECK_USETF_SLICE) == BST_CHECKED); 
   SliceViewer->SetThreshold(threshold); 
   SliceViewer->UseTransFunc(usetf); 
   SliceViewer->SetSlicePos(pos); 
   SliceViewer->glDrawSlice(); 
	GLWin->Swap(); 
} 
 
void ResetSliceDrawing(HWND hDlg, SliceOrientation so) 
{ 
   SliceViewer->SetSliceOrientation(so); 
   int num = SliceViewer->GetSliceNum(); 
   SendDlgItemMessage(hDlg, IDC_SLICE_SLIDER, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, num-1)); 
   SendDlgItemMessage(hDlg, IDC_SLICE_SLIDER, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(LONG)0); 
   DrawSlice(0); 
} 
 
void RayCastImage() 
{ 
   bool fastmode = (IsDlgButtonChecked(ParamWnd, IDC_CHECK_RM_FAST) == BST_CHECKED); 
   bool usetf = (IsDlgButtonChecked(ParamWnd, IDC_CHECK_USETF_RENDERING) == BST_CHECKED); 
   bool usehighlights = (IsDlgButtonChecked(ParamWnd, IDC_CHECK_HIGHLIGHTS) == BST_CHECKED); 
   int threshold = SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_GETPOS, 0, 0); 
   float steplength = (float)pow(2, SendDlgItemMessage(ParamWnd, IDC_SLIDER_STEPLENGTH, TBM_GETPOS, 0, 0)); 
 
   switch (rendermode) 
   { 
      case RM_THRESHOLD: 
      { 
         if (fastmode) 
         { 
            RayFirstHitNN ray(Vol, TransFunc); 
            ray.UseTransFunc(usetf); 
            ray.UseHighlights(usehighlights); 
            ray.SetStepLength(steplength); 
            ray.SetThreshold(threshold); 
            RayCast->RayCastImage(&ray, Vol); 
         } 
         else 
         { 
            RayFirstHitTL ray(Vol, TransFunc); 
            ray.UseTransFunc(usetf); 
            ray.UseHighlights(usehighlights); 
            ray.SetStepLength(steplength); 
            ray.SetThreshold(threshold); 
            RayCast->RayCastImage(&ray, Vol); 
         } 
         break; 
      } 
      case RM_MAXINTENSITY: 
      { 
         if (fastmode) 
         { 
            RayMaxIntensityNN ray(Vol, TransFunc); 
            ray.UseTransFunc(usetf); 
            ray.UseHighlights(usehighlights); 
            ray.SetStepLength(steplength); 
            RayCast->RayCastImage(&ray, Vol); 
         } 
         else 
         { 
            RayMaxIntensityTL ray(Vol, TransFunc); 
            ray.UseTransFunc(usetf); 
            ray.UseHighlights(usehighlights); 
            ray.SetStepLength(steplength); 
            RayCast->RayCastImage(&ray, Vol); 
         } 
         break; 
      } 
      case RM_TRANSPARENCY: 
      { 
         if (fastmode) 
         { 
            RayTransparencyNN ray(Vol, TransFunc); 
            ray.UseTransFunc(usetf); 
            ray.UseHighlights(usehighlights); 
            ray.SetStepLength(steplength); 
            ray.SetTransFuncVolume(TransFuncVol); 
            RayCast->RayCastImage(&ray, Vol); 
         } 
         else 
         { 
            TransFuncVol->Update(); 
            RayTransparencyTL ray(Vol, TransFunc); 
            ray.UseTransFunc(usetf); 
            ray.UseHighlights(usehighlights); 
            ray.SetStepLength(steplength); 
            ray.SetTransFuncVolume(TransFuncVol); 
            RayCast->RayCastImage(&ray, Vol); 
         } 
         break; 
      } 
   } 
} 
 
void DrawRayCastImage() 
{ 
   RayCast->glDrawImage(); 
	GLWin->Swap(); 
} 
 
void SetRayCastImageSize(int width, int height) 
{ 
   char buf[100]; 
   sprintf(buf, "Image Size: %i x %i", width, height); 
   SendDlgItemMessage(ParamWnd, IDC_TEXT_IMAGESIZE, WM_SETTEXT, 0, (LPARAM)buf); 
   RayCast->SetImageSize(width, height); 
} 
 
void SetRayStepLength(float steplength) 
{ 
   char buf[100]; 
   sprintf(buf, "Step Length: %2.3f", steplength); 
   SendDlgItemMessage(ParamWnd, IDC_TEXT_STEPLENGTH, WM_SETTEXT, 0, (LPARAM)buf); 
} 
 
void DrawOverview() 
{ 
   int threshold = SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_GETPOS, 0, 0); 
   Vol->glOverviewDraw(threshold); 
   GLWin->Swap(); 
} 
 
// ===== Mouse Handler ============================================================ 
 
int oldx = 0; 
int oldy = 0; 
 
void MouseProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(message)  
	{ 
		case WM_MOUSEMOVE: 
      { 
         if (viewmode == VM_OVERVIEW)  
         { 
            int x = LOWORD(lParam); 
            int y = HIWORD(lParam); 
            if (wParam == MK_LBUTTON) 
            { 
               if ((oldx != x) || (oldy != y)) 
               { 
                  float xr = (float)(y - oldy); 
                  float yr = (float)(x - oldx); 
                  float d = (float)sqrt(xr*xr + yr*yr); 
                  float ar = d/100; 
                  Vol->ViewRotate(ar, xr, yr, 0); 
                  DrawOverview();   
               } 
            } 
            oldx = x; 
            oldy = y; 
         } 
         break; 
      } 
   } 
} 
 
// ===== Main Window Handdler ===================================================== 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	int wmId, wmEvent; 
	switch(message)  
	{ 
		case WM_COMMAND: 
		{ 
			wmId    = LOWORD(wParam);  
			wmEvent = HIWORD(wParam);  
			// Menüauswahlen analysieren: 
			switch(wmId)  
			{ 
				case IDM_ABOUT: 
				{ 
				   DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, (DLGPROC)About); 
				   break; 
				} 
				case IDM_FILE_OPEN: 
				{ 
				   CHAR filename[512]; 
				   ZeroMemory(filename,512); 
	            OPENFILENAME ofn; 
					ZeroMemory(&ofn, sizeof(OPENFILENAME)); 
					ofn.lStructSize = sizeof(OPENFILENAME); 
		         ofn.hwndOwner = hWnd; 
			      ofn.lpstrFilter = "Volume Data Files (*.dat)\0*.dat\0Hewlett-Packard Volume Data Files (*.vol)\0*.vol\0All files (*.*)\0*.*\0"; 
				   ofn.lpstrFile = filename; 
				   ofn.nMaxFile = 511; 
               ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; 
					ofn.lpstrDefExt = "lab"; 
               if (GetOpenFileName(&ofn)) 
				   { 
						if (Vol != NULL) delete Vol; 
						if (GLWin != NULL) delete GLWin; 
                  if (TransFunc != NULL) delete TransFunc; 
                  if (TransFuncWin != NULL) delete TransFuncWin; 
                  if (SliceViewer != NULL) delete SliceViewer; 
                  if (TransFuncVol != NULL) delete TransFuncVol; 
	   				if (ParamWnd != 0) DestroyWindow(ParamWnd); 
 
						Vol = new Volume();                  
                  bool open = false; 
                  switch(ofn.nFilterIndex) 
                  { 
                     case 1: 
                        open = Vol->LoadDataDAT(ofn.lpstrFile); 
                        break; 
                     case 2: 
                        open = Vol->LoadDataVOL(ofn.lpstrFile); 
                        break; 
                  } 
                  if (!open)  
                  { 
                     char buf[100]; 
                     sprintf(buf, "Loading %s failed !", ofn.lpstrFile); 
                     MessageBox(hWnd, buf, "File loading error", MB_OK); 
   						if (Vol != NULL) delete Vol; 
                  } 
                  if (open) 
                  { 
                     // diverse objekte erzeugen 
   						GLWin = new GLWindow(hInst, hWnd, (WNDPROC)WndProc, (MOUSEPROC)MouseProc); 
                     TransFunc = new TransferFunction(); 
                     TransFuncWin = new TransferFunctionWindow(); 
                     RayCast = new RayCaster(); 
                     SliceViewer = new Slicer(Vol, TransFunc); 
                     TransFuncVol = new TransferFunctionVolume(Vol, TransFunc); 
 
                     // fenster erzeugen 
		   				ParamWnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PARAMETER), hWnd, (DLGPROC)ParameterDlgProc);				       
			   			ShowWindow(ParamWnd, SW_SHOW); 
				   		GLWnd = GLWin->GetHWND(); 
				         ShowWindow(GLWnd, SW_SHOW); 
 
                     // objekte initialisieren 
                     SliceViewer->SetSliceDrawSize(128, 128); 
                     SliceViewer->SetSliceOrientation(SO_XY); 
                     SliceViewer->SetSlicePos(0); 
                     RayCast->SetImageSize(128,128);    
                     Vol->CreateOverview(6); 
 
                     // fenster "zurechtruecken" 
						   RECT rect1, rect2; 
   						GetClientRect(hWnd, &rect1); 
	   					GetClientRect(ParamWnd, &rect2); 
		   				MoveWindow(ParamWnd, 0, 0, rect2.right-rect2.left, rect1.bottom-rect1.top, FALSE); 
			   			MoveWindow(GLWnd, rect2.right, 0, rect1.right-rect2.right, rect1.bottom-rect1.top, TRUE); 
 
                     RECT rect; 
                     GetClientRect(GLWnd, &rect); 
                     SliceViewer->SetSliceDrawSize(rect.right-rect.left, rect.bottom-rect.top); 
                     Vol->SetOverviewDrawSize(rect.right-rect.left, rect.bottom-rect.top); 
                     RayCast->SetImageDrawSize(rect.right-rect.left, rect.bottom-rect.top); 
 
                     // gui elemente initialisieren 
                     CheckRadioButton(ParamWnd, IDC_RADIO_SLICE, IDC_RADIO_VOLUME, IDC_RADIO_SLICE); 
                     CheckRadioButton(ParamWnd, IDC_RADIO_SLICE_XYPLANE, IDC_RADIO_SLICE_YZPLANE, IDC_RADIO_SLICE_XYPLANE); 
                     CheckRadioButton(ParamWnd, IDC_RADIO_RM_THRESHOLD, IDC_RADIO_RM_TRANSPARENCY, IDC_RADIO_RM_THRESHOLD); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 4095)); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(LONG)2047); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_IMAGESIZE, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(1, 16)); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_IMAGESIZE, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(LONG)8); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_STEPLENGTH, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(-3, +3)); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_STEPLENGTH, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(LONG)0); 
 
                     // default werte 
                     viewmode = VM_SLICE; 
                     rendermode = RM_THRESHOLD; 
                     ResetSliceDrawing(ParamWnd, SO_XY); 
                     SetRayCastImageSize(256, 256); 
                     SetRayStepLength(1.0f); 
                  } 
               } 
				   break; 
				} 
				case IDM_FILE_CLOSE: 
				{ 
					if (Vol != NULL) delete Vol; 
					if (GLWin != NULL) delete GLWin; 
               if (TransFunc != NULL) delete TransFunc; 
               if (TransFuncWin != NULL) delete TransFuncWin; 
               if (RayCast != NULL) delete RayCast;  
               if (SliceViewer != NULL) delete SliceViewer; 
               if (TransFuncVol != NULL) delete TransFuncVol; 
				   if (ParamWnd != 0) DestroyWindow(ParamWnd); 
               Vol = NULL; 
               GLWin = NULL; 
               TransFunc = NULL; 
               TransFuncWin = NULL; 
               RayCast = NULL; 
               SliceViewer = NULL; 
               TransFuncVol = NULL; 
					ParamWnd = 0; 
				   break; 
				} 
				case IDM_EXIT: 
				{ 
				   DestroyWindow(hWnd); 
				   break; 
				} 
			} 
			break; 
		} 
		case WM_PAINT: 
		{ 
			if ((ParamWnd != 0) && (GLWnd != 0)) 
			{ 
				PAINTSTRUCT ps; 
				BeginPaint(hWnd,&ps); 
				UpdateWindow(ParamWnd); 
 
            switch(viewmode) 
            { 
               case VM_SLICE: 
               { 
                  DrawSlice(); 
                  break; 
               } 
               case VM_OVERVIEW: 
               { 
                  DrawOverview(); 
                  break; 
               } 
               case VM_VOLUME: 
               { 
                  DrawRayCastImage(); 
                  break; 
               } 
            }          
 
				EndPaint(hWnd,&ps); 
				return 0; 
			} 
			else 
			{ 
				PAINTSTRUCT ps; 
				BeginPaint(hWnd,&ps); 
 
				BITMAP bm; 
				GetObject(hBmpVolvis, sizeof(BITMAP), &bm); 
				RECT rect; 
				GetClientRect(hWnd, &rect); 
 
				HDC hDc = GetDC(hWnd); 
				HDC hcDc = CreateCompatibleDC(hDc); 
				SelectObject(hcDc, hBmpVolvis);		 
				BitBlt(hDc, (rect.right-bm.bmWidth)/2 , (rect.bottom-bm.bmHeight)/2, bm.bmWidth, bm.bmHeight, hcDc, 0, 0, SRCCOPY); 
				 
				DeleteDC(hcDc); 
				DeleteDC(hDc); 
 
				EndPaint(hWnd, &ps); 
			} 
			break; 
		} 
      case WM_SIZE: 
		{ 
			if ((ParamWnd != 0) && (GLWnd != 0)) 
			{ 
				LONG fwSizeType = wParam;      // resizing flag  
				WORD nWidth = LOWORD(lParam);  // width of client area  
				WORD nHeight = HIWORD(lParam); // height of client area  
				RECT rect; 
				GetClientRect(ParamWnd, &rect); 
				MoveWindow(ParamWnd, 0, 0, rect.right-rect.left, nHeight, FALSE); 
				MoveWindow(GLWnd, rect.right, 0, nWidth-rect.right, nHeight, FALSE); 
				InvalidateRgn(hWnd, NULL, FALSE); 
 
            GetClientRect(GLWnd, &rect); 
            SliceViewer->SetSliceDrawSize(rect.right-rect.left, rect.bottom-rect.top); 
            Vol->SetOverviewDrawSize(rect.right-rect.left, rect.bottom-rect.top); 
            RayCast->SetImageDrawSize(rect.right-rect.left, rect.bottom-rect.top); 
				return 0; 
			} 
			else 
			{ 
				InvalidateRgn(hWnd, NULL, TRUE); 
			} 
			break; 
		} 
		case WM_DESTROY: 
		{ 
			if (Vol != NULL) delete Vol; 
      	if (GLWin != NULL) delete GLWin; 
         if (TransFunc != NULL) delete TransFunc; 
         if (TransFuncWin != NULL) delete TransFuncWin; 
         if (RayCast != NULL) delete RayCast;  
         if (SliceViewer != NULL) delete SliceViewer; 
         if (TransFuncVol != NULL) delete TransFuncVol; 
			PostQuitMessage(0); 
			break; 
		} 
   } 
	return DefWindowProc(hWnd, message, wParam, lParam); 
} 
 
//=====  Parameter Dialog Handler ===================================================== 
 
LRESULT CALLBACK ParameterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(message)  
	{ 
		case WM_INITDIALOG: 
		{ 
			return TRUE; 
		} 
      case WM_HSCROLL: 
      { 
         if ((HWND)lParam == GetDlgItem(hDlg, IDC_SLIDER_THRESHOLD)) 
         {       
            int pos = SendDlgItemMessage(hDlg, IDC_SLIDER_THRESHOLD, TBM_GETPOS, 0, 0); 
            SliceViewer->SetThreshold(pos); 
            switch(viewmode) 
            { 
               case VM_SLICE:                 
                  DrawSlice(-1); 
                  break; 
               case VM_OVERVIEW: 
                  DrawOverview(); 
                  break; 
             } 
          } 
          if ((HWND)lParam == GetDlgItem(hDlg, IDC_SLIDER_IMAGESIZE)) 
          {   
             int size = 32 * SendDlgItemMessage(hDlg, IDC_SLIDER_IMAGESIZE, TBM_GETPOS, 0, 0); 
             SetRayCastImageSize(size, size); 
          } 
          if ((HWND)lParam == GetDlgItem(hDlg, IDC_SLIDER_STEPLENGTH)) 
          {   
             float steplength = (float)pow(2,SendDlgItemMessage(hDlg, IDC_SLIDER_STEPLENGTH, TBM_GETPOS, 0, 0)); 
             SetRayStepLength(steplength); 
          } 
          break; 
      } 
      case WM_VSCROLL: 
      { 
         if ((HWND)lParam == GetDlgItem(hDlg, IDC_SLICE_SLIDER)) 
         {                 
            if (viewmode == VM_SLICE) 
            { 
               int pos = SendDlgItemMessage(hDlg, IDC_SLICE_SLIDER, TBM_GETPOS, 0, 0); 
               DrawSlice(pos); 
            } 
         }     
         break; 
      } 
		case WM_COMMAND: 
		{ 
         switch(HIWORD(wParam)) 
         { 
            case BN_CLICKED: 
            { 
               switch(LOWORD(wParam)) 
               { 
                  case IDC_BUTTON_RENDERVOLUME: 
                  { 
                     RayCastImage(); 
                     DrawRayCastImage(); 
                     break; 
                  } 
                  case IDC_BUTTON_EDITTF: 
                  { 
      	   			DialogBox(hInst, MAKEINTRESOURCE(IDD_TRANSFUNC), MainWnd, (DLGPROC)TransferFunctionDlgProc);				       
                     TransFuncVol->UpdateOnUse(); 
                     if (viewmode == VM_SLICE) DrawSlice(-1); 
                     break; 
                  } 
                  case IDC_CHECK_THRESHOLD: 
                  { 
                     bool enabled = (IsDlgButtonChecked(hDlg, IDC_CHECK_THRESHOLD) == BST_CHECKED); 
                     SliceViewer->UseThreshold(enabled); 
                     if (viewmode == VM_SLICE) DrawSlice(-1); 
                     break; 
                  } 
                  case IDC_CHECK_USETF_SLICE: 
                  { 
                     if (viewmode == VM_SLICE) DrawSlice(-1); 
                     break; 
                  } 
                  case IDC_CHECK_IMAGEISWINDOW: 
                  { 
                     bool enabled = (IsDlgButtonChecked(hDlg, IDC_CHECK_IMAGEISWINDOW) == BST_CHECKED); 
                     if (enabled) 
                     { 
                        RECT r; 
                        GetClientRect(GLWin->GetHWND(), &r); 
                        int w = r.right - r.left; 
                        int h = r.bottom - r.top; 
                        if (h > w) SetRayCastImageSize(w, w); else SetRayCastImageSize(h, h); 
                     } 
                     else 
                     { 
                        int size = 32 * SendDlgItemMessage(hDlg, IDC_SLIDER_IMAGESIZE, TBM_GETPOS, 0, 0); 
                        SetRayCastImageSize(size, size); 
                     } 
                     break; 
                  } 
                  case IDC_RADIO_VOLUME: 
                  { 
                     viewmode = VM_VOLUME; 
                     RayCast->glDrawImage(); 
         			   GLWin->Swap(); 
                     break; 
                  } 
                  case IDC_RADIO_OVERVIEW: 
                  { 
                     viewmode = VM_OVERVIEW; 
                     DrawOverview(); 
                     break; 
                  } 
                  case IDC_RADIO_SLICE: 
                  { 
                     viewmode = VM_SLICE; 
                     DrawSlice(); 
                     break; 
                  } 
                  case IDC_RADIO_RM_THRESHOLD: 
                  { 
                     rendermode = RM_THRESHOLD; 
                     break; 
                  } 
                  case IDC_RADIO_RM_MAXINTENSITY: 
                  { 
                     rendermode = RM_MAXINTENSITY; 
                     break; 
                  } 
                  case IDC_RADIO_RM_TRANSPARENCY: 
                  { 
                     rendermode = RM_TRANSPARENCY; 
                     break; 
                  } 
                  case IDC_RADIO_SLICE_XYPLANE: 
                  { 
                     switch(viewmode) 
                     { 
                        case VM_SLICE: 
                        { 
                           ResetSliceDrawing(hDlg, SO_XY); 
                           break; 
                        } 
                     } 
                     break; 
                  } 
                  case IDC_RADIO_SLICE_XZPLANE: 
                  { 
                     switch(viewmode) 
                     { 
                        case VM_SLICE: 
                        { 
                           ResetSliceDrawing(hDlg, SO_XZ); 
                           break; 
                        } 
                     } 
                     break; 
                  } 
                  case IDC_RADIO_SLICE_YZPLANE: 
                  { 
                     switch(viewmode) 
                     { 
                        case VM_SLICE: 
                        { 
                           ResetSliceDrawing(hDlg, SO_YZ); 
                           break; 
                        } 
                     } 
                     break; 
                  } 
               } 
               break; 
            } 
         } 
			break; 
		} 
	} 
   return FALSE; 
} 
 
//=====  Transfer Function Dialog Handler ============================================== 
 
enum eeditmode { EM_NONE, EM_OPACITY, EM_COLORBAR }; 
 
int tf_colorlastpos = 0; 
int tf_opacitylastpos = 0; 
eeditmode editmode = EM_NONE; 
 
void HandleTFWND(HWND hDlg, int x, int y) 
{ 
   MessageBox(0,"TFWND", "TFWND", MB_OK); 
} 
 
void HandleCBWND(HWND hDlg, int x, int y) 
{ 
   MessageBox(0,"CBWND", "CBWND", MB_OK); 
} 
 
LRESULT CALLBACK TransferFunctionDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(message) 
	{ 
		case WM_INITDIALOG: 
		{ 
         TransFuncWin->SetHistogram(Vol); 
         TransFuncWin->GetData(TransFunc); 
         int threshold = SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_GETPOS, 0, 0); 
         TransFuncWin->SetThreshold(threshold); 
         SendDlgItemMessage(hDlg, IDC_SLIDER_TFTHRESHOLD, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, 4095)); 
         SendDlgItemMessage(hDlg, IDC_SLIDER_TFTHRESHOLD, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)(LONG)threshold); 
			return TRUE; 
		} 
		case WM_COMMAND: 
		{ 
         switch(HIWORD(wParam)) 
         { 
            case BN_CLICKED: 
            { 
               switch(LOWORD(wParam)) 
               { 
                  case IDOK: 
                  { 
                     TransFuncWin->SetData(TransFunc); 
                     int threshold; 
                     TransFuncWin->GetThreshold(threshold); 
                     SendDlgItemMessage(ParamWnd, IDC_SLIDER_THRESHOLD, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)threshold); 
   			      	EndDialog(hDlg, LOWORD(wParam)); 
      	   			return TRUE; 
                     break; 
                  } 
                  case IDCANCEL: 
                  { 
         				EndDialog(hDlg, LOWORD(wParam)); 
	         			return TRUE; 
                     break; 
                  } 
                  case IDC_BUTTON_COLOR: 
                  { 
                     COLORREF custcolors[16]; 
                     CHOOSECOLOR choosecolor; 
                     choosecolor.lStructSize = sizeof(CHOOSECOLOR); 
                     choosecolor.hwndOwner = hDlg; 
                     choosecolor.hInstance = NULL; 
                     choosecolor.Flags = CC_FULLOPEN; 
                     choosecolor.lpCustColors = custcolors; 
                     choosecolor.lpTemplateName = NULL; 
                     choosecolor.lpfnHook = NULL; 
                     if (ChooseColor(&choosecolor)) 
                     { 
                        TransFuncWin->SetCurrentColor(choosecolor.rgbResult); 
                        TransFuncWin->DrawCurrentColor(hDlg); 
                     } 
                     break; 
                  } 
                  case IDC_BUTTON_BACKGROUNDCOLOR: 
                  { 
                     TransFuncWin->SetCurrentAsBackgroundColor(); 
                     TransFuncWin->DrawBackgroundColor(hDlg); 
                     break; 
                  } 
               } 
               break; 
            } 
         } 
			break; 
		} 
      case WM_HSCROLL: 
      { 
         if ((HWND)lParam == GetDlgItem(hDlg, IDC_SLIDER_TFTHRESHOLD)) 
         {       
            int threshold = SendDlgItemMessage(hDlg, IDC_SLIDER_TFTHRESHOLD, TBM_GETPOS, 0, 0); 
            TransFuncWin->SetThreshold(threshold); 
            TransFuncWin->DrawOpacity(hDlg); 
          } 
          break; 
      } 
      case WM_LBUTTONDOWN: 
      { 
         int x = LOWORD(lParam); 
         int y = HIWORD(lParam); 
         if ((x >= TFWNDX) && (x = TFWNDX+TFWNDW) && (y >= TFWNDY) && (y = TFWNDY+TFWNDH)) 
         { 
            editmode = EM_OPACITY; 
            tf_opacitylastpos = x - TFWNDX;  
         } 
         if ((x >= CBWNDX) && (x = CBWNDX+CBWNDW) && (y >= CBWNDY) && (y = CBWNDY+CBWNDH)) 
         { 
            editmode = EM_COLORBAR; 
            tf_colorlastpos = x - CBWNDX;  
         } 
         break; 
      } 
      case WM_LBUTTONUP: 
      { 
         editmode = EM_NONE; 
         break; 
      } 
      case WM_MOUSEMOVE: 
      { 
         if (wParam == MK_LBUTTON) 
         { 
            int x = LOWORD(lParam); 
            int y = HIWORD(lParam); 
 
            switch (editmode) 
            { 
               case EM_OPACITY: 
               { 
                  x -= TFWNDX; 
                  y -= TFWNDY; 
                  if (x  0) x = 0; 
                  if (y  0) y = 0; 
                  if (x > TFWNDW) x = TFWNDW; 
                  if (y > TFWNDH) y = TFWNDH; 
                  TransFuncWin->ApplyOpacity(hDlg, x, tf_opacitylastpos, 1.0f-(((float)y)/TFWNDH)); 
                  tf_opacitylastpos = x; 
                  break; 
               } 
               case EM_COLORBAR: 
               { 
                  x -= CBWNDX; 
                  y -= CBWNDY; 
                  if (x  0) x = 0; 
                  if (y  0) y = 0; 
                  if (x > CBWNDW) x = CBWNDW; 
                  if (y > CBWNDH) y = CBWNDH; 
                  TransFuncWin->ApplyColor(hDlg, x, tf_colorlastpos); 
                  tf_colorlastpos = x; 
                  break; 
               } 
            } 
         } 
         break; 
      }  
      case WM_PAINT: 
      { 
         PAINTSTRUCT ps; 
         BeginPaint(hDlg, &ps); 
         TransFuncWin->DrawOpacity(hDlg); 
         TransFuncWin->DrawColorBar(hDlg); 
         TransFuncWin->DrawCurrentColor(hDlg); 
         TransFuncWin->DrawBackgroundColor(hDlg); 
         EndPaint(hDlg, &ps); 
         break; 
      } 
	} 
   return FALSE; 
} 
 
//=====  About Dialog Handler ===================================================== 
 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch( message ) 
	{ 
		case WM_INITDIALOG: 
		{ 
			return TRUE; 
		} 
		case WM_COMMAND: 
		{ 
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  
			{ 
				EndDialog(hDlg, LOWORD(wParam)); 
				return TRUE; 
			} 
			break; 
		} 
	} 
   return FALSE; 
}