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;
}