00001
00002
00003
00004
00005
00006
00007 #include "Volumizer.h"
00008
00009 HGLRC historc;
00010 HDC histodc;
00011
00012 histo_handle *tf;
00013
00017 ATOM RegisterHistogramClass(HINSTANCE hInstance
00018 )
00019 {
00020 WNDCLASSEX wcex;
00021
00022 wcex.cbSize = sizeof(WNDCLASSEX);
00023
00024 wcex.style = CS_HREDRAW | CS_VREDRAW;
00025 wcex.lpfnWndProc = HistogramProc;
00026 wcex.cbClsExtra = 0;
00027 wcex.cbWndExtra = 0;
00028 wcex.hInstance = hInstance;
00029 wcex.hIcon = NULL;
00030 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
00031 wcex.hbrBackground = NULL;
00032 wcex.lpszMenuName = NULL;
00033 wcex.lpszClassName = L"HistogramWnd";
00034 wcex.hIconSm = NULL;
00035
00036 return RegisterClassEx(&wcex);
00037 }
00038
00042 void InitHistogramWnd(HWND hWnd)
00043 {
00044 histodc = GetDC(hWnd);
00045
00046 PIXELFORMATDESCRIPTOR pfd = {
00047 sizeof(PIXELFORMATDESCRIPTOR),
00048 1,
00049 PFD_DRAW_TO_WINDOW |
00050 PFD_SUPPORT_OPENGL |
00051 PFD_DOUBLEBUFFER,
00052 PFD_TYPE_RGBA,
00053 32,
00054 0, 0, 0, 0, 0, 0,
00055 0,
00056 0,
00057 0,
00058 0, 0, 0, 0,
00059 32,
00060 0,
00061 0,
00062 PFD_MAIN_PLANE,
00063 0,
00064 0, 0, 0
00065 };
00066
00067 int iPixelFormat;
00068
00070 iPixelFormat = ChoosePixelFormat(histodc, &pfd);
00071
00073 SetPixelFormat(histodc, iPixelFormat, &pfd);
00074
00075 if (historc = wglCreateContext( histodc ) )
00076 {
00078 wglMakeCurrent(histodc, historc) ;
00079 }
00080
00082
00083 glDisable(GL_DEPTH_TEST);
00084 glEnable(GL_POINT_SMOOTH);
00085 glEnable(GL_LINE_SMOOTH);
00086 glEnable(GL_TEXTURE_2D);
00087
00089 glEnable(GL_BLEND);
00090 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00091
00092 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
00093 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00094
00095 glClearColor(0.44f,0.44f,0.44f,0.0f);
00096
00098
00099 HFONT neuro;
00100
00101 neuro = CreateFontW(0, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, L"Arial");
00102
00103 SelectObject(histodc, neuro);
00104
00105 wglUseFontOutlines(histodc, 0, 255, 1000, 0.0f, 0.0f,
00106 WGL_FONT_LINES, NULL);
00107 }
00108
00112 void DeInitHistogramWnd(HWND hWnd)
00113 {
00114 if(historc = wglGetCurrentContext())
00115 {
00117 histodc = wglGetCurrentDC() ;
00118
00120 wglMakeCurrent(NULL, NULL) ;
00121
00123 ReleaseDC(hWnd, histodc) ;
00124
00126 wglDeleteContext(historc);
00127 }
00128 }
00129
00134 void CalcHistogram()
00135 {
00136 float classes[HISTOGRAM_SIZE];
00137 float maxclass = 0;
00138
00139 memset(classes, 0, sizeof(int)*HISTOGRAM_SIZE);
00140
00141 if (voldat)
00142 {
00143 int i = 0;
00144
00145 for (unsigned int x = 0; x < volx; x++)
00146 {
00147 for (unsigned int y = 0; y < voly; y++)
00148 {
00149 for (unsigned int z = 0; z < volz; z++)
00150 {
00154
00155 classes[(int)(voldat[i] * HISTOGRAM_SIZE)] += 1.0f;
00156
00157 if (classes[(int)(voldat[i] * HISTOGRAM_SIZE)] > maxclass)
00158 maxclass = classes[(int)(voldat[i] / HISTOGRAM_SIZE)];
00159
00160 i++;
00161 }
00162 }
00163 }
00164
00167 for (i = 0; i < HISTOGRAM_SIZE; i++)
00168 {
00169 classes[i] = (float)log((float)classes[i]);
00170 }
00171
00172 maxclass = (float)log((float)maxclass);
00173
00176 wglMakeCurrent(histodc, historc);
00177
00178 float *histotex = new float[HISTOGRAM_SIZE*256];
00179
00180 memset(histotex, 0, sizeof(float)*HISTOGRAM_SIZE*256);
00181
00182 for (int x = 0; x < HISTOGRAM_SIZE; x++)
00183 {
00184 for (int y = 0; y < 256; y++)
00185 {
00186 if (y < classes[x] * 256 / maxclass)
00187 histotex[y * HISTOGRAM_SIZE + x] = 1.0f;
00188 else
00189 histotex[y * HISTOGRAM_SIZE + x] = 0.2f;
00190 }
00191 }
00192
00193 glBindTexture(GL_TEXTURE_2D, 1);
00194
00195 glTexImage2D(GL_TEXTURE_2D,
00196 0,
00197 GL_LUMINANCE,
00198 HISTOGRAM_SIZE,
00199 256,
00200 0,
00201 GL_LUMINANCE,
00202 GL_FLOAT,
00203 histotex);
00204
00205 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
00206 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00207
00208 delete [] histotex;
00209 }
00210 }
00211
00215 void _drawBox(float x_pos,
00216 float y_pos,
00217 float delta
00218 )
00219 {
00220 glLineWidth(1.5f);
00221
00222 glBegin(GL_QUADS);
00223 glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
00224 glVertex2f(x_pos - delta, y_pos - delta);
00225 glVertex2f(x_pos - delta, y_pos + delta);
00226 glVertex2f(x_pos + delta, y_pos + delta);
00227 glVertex2f(x_pos + delta, y_pos - delta);
00228 glEnd();
00229
00230 glBegin(GL_LINES);
00231 glColor3f(1.0f, 1.0f, 1.0f);
00232 glVertex2f(x_pos - delta, y_pos - delta); glVertex2f(x_pos - delta, y_pos + delta);
00233 glVertex2f(x_pos - delta, y_pos + delta); glVertex2f(x_pos + delta, y_pos + delta);
00234 glVertex2f(x_pos + delta, y_pos + delta); glVertex2f(x_pos + delta, y_pos - delta);
00235 glVertex2f(x_pos + delta, y_pos - delta); glVertex2f(x_pos - delta, y_pos - delta);
00236 glEnd();
00237 }
00238
00244 void DrawHistogram(HWND hWnd)
00245 {
00246 wglMakeCurrent(histodc, historc);
00247
00248 RECT clientRect;
00249 GetClientRect(hWnd, &clientRect);
00250
00251 glViewport(0, 0, clientRect.right, clientRect.bottom);
00252
00253 glMatrixMode(GL_PROJECTION);
00254 glLoadIdentity();
00255
00256 float windowaspect = (float)clientRect.right / (float)clientRect.bottom;
00257
00258 gluOrtho2D(0.0f, windowaspect, 0.0f, 1.0f);
00259
00260 glMatrixMode(GL_MODELVIEW);
00261
00262 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00263
00264 glEnable(GL_TEXTURE_2D);
00265
00266 glBindTexture(GL_TEXTURE_2D, 1);
00267
00269 glBegin(GL_QUADS);
00270
00271 glColor3f(0.80f, 0.8f, 0.8f);
00272 glTexCoord2f(1.0f, 1.0f); glVertex2f(windowaspect, 1.0f);
00273
00274 glColor3f(0.4f, 0.4f, 0.4f);
00275 glTexCoord2f(1.0f, 0.0f); glVertex2f(windowaspect, 0.0f);
00276 glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
00277
00278 glColor3f(0.8f, 0.8f, 0.8f);
00279 glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f);
00280
00281 glEnd();
00282
00283 glDisable(GL_TEXTURE_2D);
00284
00286
00287 histo_handle *cur = tf;
00288
00289 while (cur)
00290 {
00291 if (cur->next)
00292 {
00294 glBegin(GL_QUADS);
00295 glColor4f(cur->col_diffuse[0], cur->col_diffuse[1], cur->col_diffuse[2], 0.5f);
00296 glVertex2f(cur->in_val * windowaspect, 0.0f);
00297 glVertex2f(cur->in_val * windowaspect, cur->out_alpha);
00298
00299 glColor4f(cur->next->col_diffuse[0], cur->next->col_diffuse[1], cur->next->col_diffuse[2], 0.5f);
00300 glVertex2f(cur->next->in_val * windowaspect, cur->next->out_alpha);
00301 glVertex2f(cur->next->in_val * windowaspect, 0.0f);
00302 glEnd();
00303
00305 glLineWidth(2.5f);
00306 glBegin(GL_LINES);
00307 glColor3f(1.0f, 1.0f, 1.0f);
00308
00309 glVertex2f(cur->in_val * windowaspect, cur->out_alpha);
00310 glVertex2f(cur->next->in_val * windowaspect, cur->next->out_alpha);
00311 glEnd();
00312
00313 glLineWidth(1.0f);
00314 glBegin(GL_LINES);
00315 glColor3f(0.0f, 0.0f, 0.0f);
00316
00317 glVertex2f(cur->in_val * windowaspect, cur->out_alpha);
00318 glVertex2f(cur->next->in_val * windowaspect, cur->next->out_alpha);
00319 glEnd();
00320 }
00321
00323 _drawBox(cur->in_val * windowaspect, cur->out_alpha, HANDLE_SIZE);
00324
00325 cur = cur->next;
00326 }
00327
00328 glFinish();
00329
00330 SwapBuffers(histodc);
00331 }
00332
00336 void CreateDefaultHandle(histo_handle &handle
00337 )
00338 {
00339 handle.prev = NULL;
00340 handle.next = NULL;
00341
00342 handle.col_ambient[0] = 0.1f;
00343 handle.col_ambient[1] = 0.1f;
00344 handle.col_ambient[2] = 0.1f;
00345
00346 handle.col_diffuse[0] = 0.5f;
00347 handle.col_diffuse[1] = 0.5f;
00348 handle.col_diffuse[2] = 0.5f;
00349
00350 handle.col_specular[0] = 0.8f;
00351 handle.col_specular[1] = 0.8f;
00352 handle.col_specular[2] = 0.8f;
00353
00354 handle.spec_exponent = 0.1f;
00355
00356 handle.gradient = 0.0f;
00357 }
00358
00363 void CreateInterpolatedHandle(histo_handle &newone,
00364 float new_pos
00365 )
00366 {
00367 CreateDefaultHandle(newone);
00368
00370 histo_handle *pre, *post;
00371
00372 pre = post = tf;
00373
00374 while (post)
00375 {
00376 if (post->in_val >= new_pos)
00377 {
00378 if (pre == post)
00379 post = post->next;
00380
00381 break;
00382 }
00383
00384 pre = post;
00385
00386 post = post->next;
00387 }
00388
00390 float dist = post->in_val - pre->in_val;
00391
00392 float weight = (new_pos - pre->in_val) / dist;
00393
00395 newone.col_ambient[0] = pre->col_ambient[0] * (1.0f - weight) + post->col_ambient[0] * weight;
00396 newone.col_ambient[1] = pre->col_ambient[1] * (1.0f - weight) + post->col_ambient[1] * weight;
00397 newone.col_ambient[2] = pre->col_ambient[2] * (1.0f - weight) + post->col_ambient[2] * weight;
00398
00399 newone.col_diffuse[0] = pre->col_diffuse[0] * (1.0f - weight) + post->col_diffuse[0] * weight;
00400 newone.col_diffuse[1] = pre->col_diffuse[1] * (1.0f - weight) + post->col_diffuse[1] * weight;
00401 newone.col_diffuse[2] = pre->col_diffuse[2] * (1.0f - weight) + post->col_diffuse[2] * weight;
00402
00403 newone.col_specular[0] = pre->col_specular[0] * (1.0f - weight) + post->col_specular[0] * weight;
00404 newone.col_specular[1] = pre->col_specular[1] * (1.0f - weight) + post->col_specular[1] * weight;
00405 newone.col_specular[2] = pre->col_specular[2] * (1.0f - weight) + post->col_specular[2] * weight;
00406
00407 newone.spec_exponent = pre->spec_exponent * (1.0f - weight) + post->spec_exponent * weight;
00408
00409 newone.out_alpha = pre->out_alpha * (1.0f - weight) + post->out_alpha * weight;
00410
00411 newone.gradient = pre->gradient * (1.0f - weight) + post->gradient * weight;
00412
00413 newone.in_val = new_pos;
00414 }
00415
00419 histo_handle *GropeForHandle(HWND hWnd)
00420 {
00421 POINT cpos;
00422
00423 GetCursorPos(&cpos);
00424
00425 ScreenToClient(hWnd, &cpos);
00426
00427 RECT clientRect;
00428 GetClientRect(hWnd, &clientRect);
00429
00430 float windowaspect = (float)clientRect.right / (float)clientRect.bottom;
00431
00433 wglMakeCurrent(histodc, historc);
00434
00435 double mvm[16];
00436 glGetDoublev(GL_MODELVIEW_MATRIX, mvm);
00437 double pm[16];
00438 glGetDoublev(GL_PROJECTION_MATRIX, pm);
00439 int view[4];
00440 glGetIntegerv(GL_VIEWPORT, view);
00441
00442 double ox, oy, oz;
00443
00444 gluUnProject(cpos.x, cpos.y, 0.0, mvm, pm, view, &ox, &oy, &oz);
00445
00446 oy = 1.0f - oy;
00447
00449 histo_handle *cur = tf;
00450
00451 while (cur)
00452 {
00453 if (ox > cur->in_val * windowaspect - HANDLE_SIZE &&
00454 ox < cur->in_val * windowaspect + HANDLE_SIZE &&
00455 oy > cur->out_alpha - HANDLE_SIZE &&
00456 oy < cur->out_alpha + HANDLE_SIZE)
00457 {
00458 SetCursor(LoadCursor(NULL, IDC_HAND));
00459 return cur;
00460 }
00461
00462 cur = cur->next;
00463 }
00464
00465 return NULL;
00466 }
00467
00471 void MoveHandle(HWND hWnd, histo_handle *handle)
00472 {
00473 POINT cpos;
00474
00475 GetCursorPos(&cpos);
00476
00477 ScreenToClient(hWnd, &cpos);
00478
00479 RECT clientRect;
00480 GetClientRect(hWnd, &clientRect);
00481
00482 float windowaspect = (float)clientRect.right / (float)clientRect.bottom;
00483
00484 wglMakeCurrent(histodc, historc);
00485
00486 double mvm[16];
00487 glGetDoublev(GL_MODELVIEW_MATRIX, mvm);
00488 double pm[16];
00489 glGetDoublev(GL_PROJECTION_MATRIX, pm);
00490 int view[4];
00491 glGetIntegerv(GL_VIEWPORT, view);
00492
00493 double ox, oy, oz;
00494
00495 gluUnProject(cpos.x, cpos.y, 0.0, mvm, pm, view, &ox, &oy, &oz);
00496
00497 oy = 1.0f - oy;
00498 oy = (oy > 1.0f)?1.0f:((oy < 0.0f)?0.0f:oy);
00499 handle->out_alpha = (float)oy;
00500
00501 ox /= windowaspect;
00502
00503 if (handle->prev &&
00504 handle->next)
00505 {
00506 if (ox < handle->prev->in_val)
00507 ox = handle->prev->in_val + 0.001f;
00508
00509 if (ox > handle->next->in_val)
00510 ox = handle->next->in_val - 0.001f;
00511
00512 handle->in_val = (float)ox;
00513 }
00514
00515 DrawHistogram(hWnd);
00516 }
00517
00521 histo_handle *InsertHandle(HWND hWnd)
00522 {
00523 POINT cpos;
00524
00525 GetCursorPos(&cpos);
00526
00527 ScreenToClient(hWnd, &cpos);
00528
00529 RECT clientRect;
00530 GetClientRect(hWnd, &clientRect);
00531
00532 float windowaspect = (float)clientRect.right / (float)clientRect.bottom;
00533
00534 wglMakeCurrent(histodc, historc);
00535
00536 double mvm[16];
00537 glGetDoublev(GL_MODELVIEW_MATRIX, mvm);
00538 double pm[16];
00539 glGetDoublev(GL_PROJECTION_MATRIX, pm);
00540 int view[4];
00541 glGetIntegerv(GL_VIEWPORT, view);
00542
00543 double ox, oy, oz;
00544
00545 gluUnProject(cpos.x, cpos.y, 0.0, mvm, pm, view, &ox, &oy, &oz);
00546
00547 oy = 1.0f - oy;
00548 ox /= windowaspect;
00549
00550 histo_handle *cur = tf;
00551 histo_handle *handle = NULL;
00552
00553 while (cur)
00554 {
00555 if (cur->in_val > ox)
00556 {
00557 handle = new histo_handle;
00558 CreateInterpolatedHandle(*handle, (float)ox);
00559
00560 handle->prev = cur->prev;
00561 handle->next = cur;
00562
00563 handle->prev->next = handle;
00564 handle->next->prev = handle;
00565
00566 handle->in_val = (float)ox;
00567 handle->out_alpha = (float)oy;
00568
00569 break;
00570 }
00571
00572 cur = cur->next;
00573 }
00574
00575 DrawHistogram(hWnd);
00576
00577 return handle;
00578 }
00579
00583 void CreateDefaultTransferFunction()
00584 {
00585
00586 tf = new histo_handle;
00587
00588 CreateDefaultHandle(*tf);
00589 tf->prev = NULL;
00590 tf->in_val = 0.0f;
00591 tf->out_alpha = 0.0f;
00592
00593 tf->next = new histo_handle;
00594
00595 CreateDefaultHandle(*(tf->next));
00596 tf->next->prev = tf;
00597 tf->next->next = NULL;
00598 tf->next->in_val = 1.0f;
00599 tf->next->out_alpha = 1.0f;
00600 }
00601
00605 void LoadFunction()
00606 {
00607 OPENFILENAME ofn;
00608 ofn.lStructSize = sizeof(OPENFILENAME);
00609 ofn.hwndOwner = wnd_histogram;
00610 ofn.hInstance = NULL;
00611 ofn.lpstrFilter = L"Transfer Function (*.tf)\0*.TF\0All Files\0*.*\0\0";
00612 ofn.lpstrCustomFilter = NULL;
00613 ofn.nMaxCustFilter = 0;
00614 ofn.nFilterIndex = 1;
00615 ofn.lpstrFile = new wchar_t[500]; ofn.lpstrFile[0] = '\0';
00616 ofn.nMaxFile = 500;
00617 ofn.lpstrFileTitle = NULL;
00618 ofn.nMaxFileTitle = 0;
00619 ofn.lpstrInitialDir = NULL;
00620 ofn.lpstrTitle = NULL;
00621 ofn.Flags = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
00622 ofn.lpstrDefExt = NULL;
00623 ofn.pvReserved = NULL;
00624 ofn.dwReserved = 0;
00625 ofn.FlagsEx = 0;
00626
00627
00628 if (GetOpenFileName(&ofn))
00629 {
00630
00631 histo_handle *cur = tf;
00632
00633 while (cur->next)
00634 {
00635 cur = cur->next;
00636
00637 delete cur->prev;
00638 }
00639
00640 delete cur;
00641
00642
00643 int infile;
00644 _wsopen_s(&infile, ofn.lpstrFile, _O_BINARY | _O_SEQUENTIAL, _SH_DENYNO, 0);
00645
00646
00647 tf = new histo_handle;
00648
00649
00650 _read(infile, tf, sizeof(histo_handle));
00651
00652 cur = tf;
00653
00654
00655 while (cur->next)
00656 {
00657 cur->next = new histo_handle;
00658
00659 _read(infile, cur->next, sizeof(histo_handle));
00660 cur->next->prev = cur;
00661
00662 cur = cur->next;
00663 }
00664
00665
00666 _close(infile);
00667 }
00668 }
00669
00673 void SaveFunction()
00674 {
00675 OPENFILENAME ofn;
00676
00677 ofn.lStructSize = sizeof(OPENFILENAME);
00678 ofn.hwndOwner = wnd_histogram;
00679 ofn.hInstance = NULL;
00680 ofn.lpstrFilter = L"Transfer Function (*.tf)\0*.TF\0All Files\0*.*\0\0";
00681 ofn.lpstrCustomFilter = NULL;
00682 ofn.nMaxCustFilter = 0;
00683 ofn.nFilterIndex = 1;
00684 ofn.lpstrFile = new wchar_t[500]; ofn.lpstrFile[0] = '\0';
00685 ofn.nMaxFile = 500;
00686 ofn.lpstrFileTitle = NULL;
00687 ofn.nMaxFileTitle = 0;
00688 ofn.lpstrInitialDir = NULL;
00689 ofn.lpstrTitle = NULL;
00690 ofn.Flags = OFN_DONTADDTORECENT;
00691 ofn.lpstrDefExt = NULL;
00692 ofn.pvReserved = NULL;
00693 ofn.dwReserved = 0;
00694 ofn.FlagsEx = 0;
00695
00696
00697 if (GetSaveFileName(&ofn))
00698 {
00699
00700 int outfile;
00701
00702 _wsopen_s(&outfile, ofn.lpstrFile, _O_BINARY | _O_SEQUENTIAL | _O_CREAT | _O_WRONLY | _O_TRUNC, _SH_DENYNO, _S_IWRITE | _S_IREAD);
00703
00704 histo_handle *cur = tf;
00705
00706 while (cur)
00707 {
00708 _write(outfile, cur, sizeof(histo_handle));
00709 cur = cur->next;
00710 }
00711
00712
00713 _close(outfile);
00714 }
00715 }
00716
00720 LRESULT CALLBACK HistogramProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
00721 {
00722 PAINTSTRUCT ps;
00723 HDC hdc;
00724
00725 static histo_handle *handle;
00726 HMENU pop;
00727
00728 switch (message)
00729 {
00730 case WM_RBUTTONDOWN:
00733 handle = GropeForHandle(hWnd);
00734
00735 if (handle)
00736 {
00737 POINT cpos;
00738
00739 GetCursorPos(&cpos);
00740
00741 pop = LoadMenu(hInst, MAKEINTRESOURCE(IDC_RCLICKS));
00742
00743 if (handle->prev && handle->next)
00744 EnableMenuItem(pop, ID_HANDLE_REMOVE, MF_ENABLED);
00745 else
00746 EnableMenuItem(pop, ID_HANDLE_REMOVE, MF_DISABLED);
00747
00748 UINT resp = TrackPopupMenuEx(GetSubMenu(pop, 0), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, cpos.x, cpos.y, hWnd, NULL);
00749
00750 if (resp == ID_HANDLE_REMOVE)
00751 {
00752 handle->prev->next = handle->next;
00753 handle->next->prev = handle->prev;
00754
00755 delete handle;
00756
00757 DrawHistogram(hWnd);
00758 }
00759 else if (resp == ID_HANDLE_EDIT)
00760 {
00761 EditTransferHandle(handle, hWnd);
00762 }
00763 }
00764 else
00765 {
00766 POINT cpos;
00767
00768 GetCursorPos(&cpos);
00769
00770 pop = LoadMenu(hInst, MAKEINTRESOURCE(IDC_RCLICKS));
00771 UINT resp = TrackPopupMenuEx(GetSubMenu(pop, 1), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD, cpos.x, cpos.y, hWnd, NULL);
00772
00773 if (resp == ID_BACK_LOADTRANSFERFUNCTION)
00774 {
00775 LoadFunction();
00776 DrawHistogram(hWnd);
00777 RayRender();
00778 }
00779 else if (resp == ID_BACK_SAVETRANSFERFUNCTION)
00780 {
00781 SaveFunction();
00782 }
00783 }
00784
00785 break;
00786 case WM_LBUTTONDOWN:
00789 handle = GropeForHandle(hWnd);
00790 SetCapture(hWnd);
00791
00792 if (!handle)
00793 {
00794 handle = InsertHandle(hWnd);
00795 }
00796
00797 break;
00798 case WM_LBUTTONUP:
00799 ReleaseCapture();
00800 case WM_MOUSEMOVE:
00802 if (GetCapture() == hWnd)
00803 {
00804 if (handle)
00805 {
00806 MoveHandle(hWnd, handle);
00807 }
00808 }
00809 else
00810 {
00811 GropeForHandle(hWnd);
00812 }
00813 break;
00814 case WM_PAINT:
00815 hdc = BeginPaint(hWnd, &ps);
00816 DrawHistogram(hWnd);
00817 EndPaint(hWnd, &ps);
00818 break;
00819 case WM_SHOWWINDOW:
00820 InitHistogramWnd(hWnd);
00821 break;
00822 case WM_DESTROY:
00823 DeInitHistogramWnd(hWnd);
00824 PostQuitMessage(0);
00825 break;
00826 default:
00827 return DefWindowProc(hWnd, message, wParam, lParam);
00828 }
00829 return 0;
00830 }