00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #include "camtypes.h"
00118 #include "customlist.h"
00119
00120 #ifdef _DEBUG
00121 #define new DEBUG_NEW
00122 #undef THIS_FILE
00123 static char THIS_FILE[] = __FILE__;
00124 #endif
00125
00129
00130
00131
00135
00136 const INT32 CCustomList::MAXCOLUMNS = 8;
00137 const INT32 CCustomList::MAXROWS = 100;
00138 const INT32 CCustomList::FONTHEIGHT = 14;
00139 const INT32 CCustomList::ROWHEIGHT = 17 ;
00140 const INT32 CCustomList::COLOUR_PATCH_WIDTH = 12 ;
00141 const INT32 CCustomList::COLOUR_PATCH_HEIGHT = 12 ;
00142 const CString CCustomList::WNDCLASSNAME = "cc_CustomList";
00143
00144 BEGIN_MESSAGE_MAP(CCustomList, CWnd)
00145
00146 ON_WM_CREATE()
00147 ON_WM_VSCROLL()
00148 ON_WM_SETFOCUS()
00149 ON_WM_MOUSEWHEEL()
00150
00151 END_MESSAGE_MAP()
00152
00153
00154 CCustomList::CCustomList() :
00155 m_VScrollBar(NULL),
00156 m_ScrollableArea(NULL)
00157 {
00158
00159 m_ColumnOffsetsArray = new INT32[MAXCOLUMNS];
00160 m_ColumnOffsetsArray[0] = 10;
00161 for( INT32 i=1; i < MAXCOLUMNS ; i++)
00162 m_ColumnOffsetsArray[i] = -1;
00163 }
00164
00165
00166
00167
00168 extern "C" LRESULT CALLBACK EXPORT CCustomList::CustomWindowProc(HWND hWnd, UINT32 nMsg, WPARAM wParam, LPARAM lParam)
00169 {
00170
00171 CCustomList* pWnd = new CCustomList;
00172 pWnd->Attach(hWnd);
00173
00174 ::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)AfxWndProc);
00175
00176 return ::CallWindowProc(AfxWndProc, hWnd, nMsg, wParam, lParam);
00177 }
00178
00179
00180
00181
00182 BOOL CCustomList::RegisterWindowClass()
00183 {
00184 HINSTANCE hInst = AfxGetInstanceHandle();
00185 WNDCLASS wc;
00186 if (!(::GetClassInfo(hInst, WNDCLASSNAME, &wc)))
00187 {
00188
00189 wc.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS ;
00190 wc.lpfnWndProc = (WNDPROC) CCustomList::CustomWindowProc;
00191 wc.cbClsExtra = wc.cbWndExtra = 0;
00192 wc.hInstance = hInst;
00193 wc.hIcon = NULL;
00194 wc.hCursor = LoadCursor (NULL, _R(IDC_ARROW));
00195 wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
00196 wc.lpszMenuName = (LPSTR) NULL;
00197 wc.lpszClassName = (LPCTSTR) WNDCLASSNAME;
00198
00199
00200 if (!RegisterClass (&wc))
00201 {
00202 ASSERT(FALSE);
00203 return FALSE;
00204 }
00205 }
00206 return TRUE;
00207 }
00208
00209 CCustomList::~CCustomList()
00210 {
00211
00212 delete m_ColumnOffsetsArray;
00213
00214 delete m_VScrollBar ;
00215 }
00216
00217
00218 void CCustomList::PostNcDestroy()
00219 {
00220 delete this;
00221 CWnd::PostNcDestroy();
00222 }
00223
00224
00225
00226 CCustomList* CCustomList::GetGadget(CWindowID hDlg, CGadgetID nIDDlgItem)
00227 {
00228 HWND listwnd = ::GetDlgItem(hDlg, nIDDlgItem);
00229 CCustomList* pListGadget = (CCustomList*)CWnd::FromHandlePermanent(listwnd);
00230 return pListGadget ;
00231 }
00232
00233
00234
00235 BOOL CCustomList::AddItem(StringBase& itemString, KernelBitmap* pItemImage)
00236 {
00237 CCustomListRowWnd* pNewRow = GetScrollableArea()->AddRow();
00238 pNewRow ->AddCheck(0);
00239 pNewRow ->AddText(1,(TCHAR *)itemString);
00240 return TRUE;
00241 }
00242
00243
00244 BOOL CCustomList::AddRefsItem(UINT32 idStatusBitmap, StringBase& strItemName, StringBase& strDetails)
00245 {
00246 CCustomListRowWnd* pNewRow = GetScrollableArea()->AddRow();
00247 if (pNewRow)
00248 {
00249 if (idStatusBitmap!=0)
00250 {
00251 HBITMAP hBitmap = LoadBitmap(AfxGetResourceHandle(), MAKEINTRESOURCE(idStatusBitmap));
00252 pNewRow->AddBitmap(0, hBitmap, NULL, 0xFFFFFF);
00253 }
00254 pNewRow->AddText(1, (TCHAR*)strItemName);
00255 pNewRow->AddText(2, (TCHAR*)strDetails);
00256 return TRUE;
00257 }
00258
00259 return FALSE;
00260 }
00261
00262
00263 BOOL CCustomList::GetItemString(StringBase& itemString, UINT32 itemIndex, UINT32 columnIndex) const
00264 {
00265 CString s = GetScrollableArea()->GetRow(itemIndex)->GetText(columnIndex);
00266 itemString.Empty();
00267 itemString+= s;
00268 return TRUE;
00269 }
00270
00271
00272 BOOL CCustomList::GetSwitchState(UINT32 itemIndex, UINT32 switchIndex) const
00273 {
00274 return GetScrollableArea()->GetRow(itemIndex)->IsChecked(switchIndex);
00275 }
00276
00277
00278 INT32 CCustomList::GetItemCount() const
00279 {
00280 return GetScrollableArea()->m_RowCount;
00281 }
00282
00283
00284 INT32 CCustomList::GetSelectedItemIndex() const
00285 {
00286 return GetScrollableArea()->m_CurrentSelectedRow;
00287 }
00288
00289
00290 BOOL CCustomList::SetSwitchState(BOOL state, UINT32 itemIndex, UINT32 switchIndex)
00291 {
00292 GetScrollableArea()->GetRow(itemIndex)->SetChecked(switchIndex,state);
00293 return TRUE;
00294 }
00295
00296
00297 BOOL CCustomList::AddItem(StringBase& itemString, UINT32 bitmapEnabledID, UINT32 bitmapDisabledID)
00298 {
00299 HBITMAP hItemBitmapEnabled = LoadBitmap (AfxGetResourceHandle(),MAKEINTRESOURCE(bitmapEnabledID));
00300
00301
00302
00303
00304 CCustomListRowWnd* pNewRow = GetScrollableArea()->AddRow();
00305 pNewRow ->AddCheck(0);
00306 pNewRow ->AddBitmap(1,hItemBitmapEnabled,NULL);
00307 pNewRow ->AddText(2,(TCHAR *)itemString);
00308
00309 return TRUE;
00310 }
00311
00312
00313 void CCustomList::SetSelectedItemIndex(INT32 NewSel)
00314 {
00315 GetScrollableArea()->SelectRow(NewSel);
00316 }
00317
00318
00319 BOOL CCustomList::DeleteAllItems()
00320 {
00321 if(m_ScrollableArea)
00322 {
00323 m_ScrollableArea->DestroyWindow();
00324
00325 }
00326 NewScrollableArea();
00327 return TRUE;
00328 }
00329
00330
00331 void CCustomList::NewScrollableArea()
00332 {
00333 m_ScrollableArea = new CCustomListScrollableArea(this);
00334 BOOL b = m_ScrollableArea->Create(_T("STATIC"), NULL, WS_CHILD | WS_VISIBLE,CRect(0,0,0,0),this,0,NULL);
00335 }
00336
00337
00338 INT32 CCustomList::OnCreate(LPCREATESTRUCT lpCreateStruct)
00339 {
00340 if (CWnd::OnCreate(lpCreateStruct) == -1)
00341 return -1;
00342
00343 m_VScrollBar = new CScrollBar();
00344 CRect parentRect;
00345 CRect rect;
00346 GetClientRect(&parentRect);
00347 rect.left = parentRect.right - ::GetSystemMetrics(SM_CXVSCROLL) ;
00348 rect.top = 0;
00349 rect.right = parentRect.right ;
00350 rect.bottom = parentRect.bottom ;
00351 m_VScrollBar->Create(SBS_VERT, rect, this, NULL);
00352 m_VScrollBar->ShowWindow(SW_SHOW);
00353
00354 NewScrollableArea();
00355
00356 return 0;
00357 }
00358
00359
00360 void CCustomList::OnVScroll(UINT32 nSBCode, UINT32 nPos, CScrollBar* pScrollBar)
00361 {
00362 m_ScrollableArea->HandleScrollMessage(nSBCode, nPos) ;
00363 CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
00364 }
00365
00366
00367 HBITMAP CreateScreenCompatibleBitmap( INT32 width, INT32 height)
00368 {
00369 HDC hProbeDC = ::CreateCompatibleDC(NULL);
00370 ERROR3IF(hProbeDC == NULL, "Couldn't create probe DC");
00371 const BITMAP bitmapData =
00372 {
00373 0,
00374 width,
00375 height,
00376 width * GetDeviceCaps(hProbeDC, BITSPIXEL) * GetDeviceCaps(hProbeDC, PLANES) / 8 ,
00377 GetDeviceCaps(hProbeDC, PLANES),
00378 GetDeviceCaps(hProbeDC, BITSPIXEL),
00379 0L
00380 };
00381 DeleteDC(hProbeDC);
00382 return CreateBitmapIndirect(&bitmapData);
00383 }
00384
00385
00386 BOOL CCustomList::AddColourListItem(StringBase& colourName, INT32 red, INT32 green, INT32 blue, BOOL IsSpotColour)
00387 {
00388
00389
00390 HDC hDC = ::CreateCompatibleDC(NULL);
00391 ERROR3IF(hDC == NULL, "Couldn't create rendering DC");
00392
00393
00394
00395 HBITMAP bitmaps[1];
00396 bitmaps[0] = CreateScreenCompatibleBitmap(COLOUR_PATCH_WIDTH, COLOUR_PATCH_HEIGHT);
00397
00398
00399
00400
00401 for (INT32 i = 0; i <= 1; i++)
00402 {
00403 if (hDC != NULL)
00404 {
00405 HBITMAP OldBitmap = (HBITMAP) ::SelectObject(hDC, bitmaps[i]);
00406
00407 COLORREF Colour = RGB(red, green, blue);
00408 if (i != 0)
00409 {
00410
00411 BYTE Grey = BYTE((red * 0.305) + (green * 0.586) + (blue * 0.109));
00412 Colour = RGB(Grey, Grey, Grey);
00413 }
00414
00415 HBRUSH Brush = ::CreateSolidBrush(Colour);
00416
00417 ERROR3IF(Brush == NULL, "Couldn't create brush");
00418
00419 HPEN BlackPen = (HPEN) ::GetStockObject(BLACK_PEN);
00420
00421 HBRUSH WhiteBrush = (HBRUSH) ::GetStockObject(WHITE_BRUSH);
00422 HPEN NullPen = (HPEN) ::GetStockObject(NULL_PEN);
00423 HPEN OldPen = (HPEN) ::SelectObject(hDC, NullPen);
00424 HBRUSH OldBrush = (HBRUSH) ::SelectObject(hDC, WhiteBrush);
00425 if (IsSpotColour)
00426 {
00427
00428
00429
00430 ::Rectangle(hDC, 0, 0, COLOUR_PATCH_WIDTH+1, COLOUR_PATCH_HEIGHT+1);
00431 ::SelectObject(hDC, BlackPen);
00432 ::SelectObject(hDC, Brush);
00433 ::Ellipse(hDC, 0, 0, COLOUR_PATCH_WIDTH, COLOUR_PATCH_HEIGHT);
00434
00435 }
00436 else
00437 {
00438
00439
00440 ::Rectangle(hDC, 0, 0, COLOUR_PATCH_WIDTH+1, COLOUR_PATCH_HEIGHT+1);
00441 ::SelectObject(hDC, BlackPen);
00442 ::SelectObject(hDC, Brush);
00443 ::Rectangle(hDC, 0, 0, COLOUR_PATCH_WIDTH-1, COLOUR_PATCH_HEIGHT-1);
00444
00445 }
00446
00447 ::SelectObject(hDC, OldPen);
00448 ::SelectObject(hDC, OldBrush);
00449 ::SelectObject(hDC, OldBitmap);
00450
00451 ::DeleteObject(Brush);
00452 }
00453 }
00454
00455 DeleteDC(hDC);
00456
00457 CCustomListRowWnd* pNewRow = GetScrollableArea()->AddRow();
00458 pNewRow ->AddCheck(0);
00459 pNewRow ->AddCheck(1);
00460 pNewRow ->AddBitmap(2,bitmaps[0],NULL);
00461 pNewRow ->AddText(3,(TCHAR*)colourName);
00462
00463 return TRUE;
00464 }
00465
00466
00467 BOOL CCustomList::SetItemString(StringBase& itemString, UINT32 itemIndex, UINT32 columnIndex)
00468 {
00469 GetScrollableArea()->GetRow(itemIndex)->SetText(columnIndex,(TCHAR*) itemString);
00470 return TRUE;
00471 }
00472
00473
00474 void EnableDescendants(HWND hWnd, BOOL enable)
00475 {
00476
00477
00478 for (HWND hWndChild = ::GetTopWindow(hWnd); hWndChild != NULL;
00479 hWndChild = ::GetNextWindow(hWndChild, GW_HWNDNEXT))
00480 {
00481 CWnd* pWnd = CWnd::FromHandlePermanent(hWndChild);
00482 if (pWnd != NULL)
00483 {
00484 pWnd->EnableWindow(enable);
00485 pWnd->RedrawWindow();
00486 }
00487 if (::GetTopWindow(hWndChild) != NULL)
00488 {
00489
00490 EnableDescendants(hWndChild,enable);
00491 }
00492 }
00493 }
00494
00495
00496
00497 BOOL CCustomList::SetEnabled(BOOL enabled)
00498 {
00499 GetScrollableArea()->SelectRow(-1);
00500 EnableWindow(enabled);
00501 EnableDescendants(m_hWnd,enabled);
00502 return TRUE;
00503 }
00504
00505
00506 void CCustomList::SetColumnWidth(INT32 colnum,INT32 colwidth)
00507 {
00508 ASSERT(colnum + 1 < MAXCOLUMNS);
00509
00510
00512 ERROR3IF(m_ColumnOffsetsArray[colnum]==-1,"SetColumnWidth - illegal column offset. ensure preceding column widths are set");
00513 m_ColumnOffsetsArray[colnum+1] = m_ColumnOffsetsArray[colnum] + colwidth;
00514 }
00515
00516
00517 BOOL SetBitmapBkgToSystem(HBITMAP hBitmap)
00518 {
00519 BITMAP bitmap;
00520 HDC hBitmapDC = CreateCompatibleDC(NULL);
00521 if (!GetObject(hBitmap, sizeof(bitmap), &bitmap) || !hBitmapDC)
00522 {
00523 ERROR2RAW("Non-fatal GDI error");
00524 return(FALSE);
00525 }
00526 SelectObject(hBitmapDC, hBitmap);
00527
00528 DWORD currentBkColour = (DWORD) GetPixel(hBitmapDC, bitmap.bmWidth - 1, bitmap.bmHeight -1);
00529 DWORD sysBkColour = GetSysColor(COLOR_3DFACE);
00530 for (INT32 i = 0; i < bitmap.bmWidth; i++)
00531 {
00532 for (INT32 j = 0; j < bitmap.bmHeight; j++)
00533 {
00534 if ((DWORD) GetPixel(hBitmapDC, i, j) == currentBkColour)
00535 SetPixelV(hBitmapDC, i, j, (COLORREF) sysBkColour);
00536 }
00537 }
00538 DeleteDC(hBitmapDC);
00539 return TRUE;
00540 }
00541
00542
00543 BOOL CCustomList::CreateCustomHeader(UINT32 bitmapID)
00544 {
00545
00546
00547
00548 CRect listviewRect;
00549 GetWindowRect(&listviewRect);
00550 POINT listviewOrigin = { listviewRect.left, listviewRect.top };
00551 ::ScreenToClient((HWND) GetOwner()->m_hWnd, &listviewOrigin);
00552
00553 if(!m_hHeaderBitmap.LoadBitmap(MAKEINTRESOURCE(bitmapID)))
00554 ERROR2RAW("Failed to load header bitmap");
00555
00556
00557 BITMAP bitmap ;
00558 if (!m_hHeaderBitmap.GetBitmap(&bitmap))
00559 {
00560 ERROR2RAW("Failed to get header bitmap data");
00561 return(FALSE);
00562 }
00563
00564 SetBitmapBkgToSystem(m_hHeaderBitmap);
00565
00566 CRect srect;
00567 srect.left = listviewOrigin.x + m_ColumnOffsetsArray[0] + 1;
00568 srect.right = listviewRect.right ;
00569 srect.top = listviewOrigin.y - bitmap.bmHeight;
00570 srect.bottom = listviewOrigin.y;
00571
00572 m_hHeader.Create(NULL, WS_VISIBLE | SS_BITMAP, srect, this->GetOwner());
00573 m_hHeader.SetBitmap(m_hHeaderBitmap);
00574 return TRUE;
00575 }
00576
00577
00578
00579
00580 void CCustomList::OnSetFocus(CWnd* pOldWnd)
00581 {
00582 CWnd::OnSetFocus(pOldWnd);
00583
00584 if(GetScrollableArea()->GetSafeHwnd()!=NULL)
00585 {
00586 if(GetScrollableArea()->m_RowCount > 0 && GetScrollableArea()->m_ListRowsArray)
00587 {
00588 INT32 Sel = GetScrollableArea()->m_CurrentSelectedRow;
00589 if(Sel==-1 || GetScrollableArea()->m_CurrentSelectedRow > GetScrollableArea()->m_RowCount)
00590 Sel=0;
00591 GetScrollableArea()->SelectRow(Sel);
00592 }
00593 }
00594
00595 }
00596
00600
00601
00602
00606
00607 BEGIN_MESSAGE_MAP(CCustomListScrollableArea, CWnd)
00608
00609 ON_WM_SIZE()
00610
00611 END_MESSAGE_MAP()
00612
00613
00614 CCustomListScrollableArea::CCustomListScrollableArea(CCustomList* parent) :
00615 m_CurrentSelectedRow(-1),
00616 m_RowCount(0),
00617 m_Parent(parent),
00618 m_ListRowsArray(NULL),
00619 m_ScrollPos(0)
00620 {
00621
00622 LOGFONT lf;
00623 memset(&lf, 0, sizeof(LOGFONT));
00624 lf.lfHeight = CCustomList::FONTHEIGHT;
00625 strcpy(lf.lfFaceName, "Microsoft Sans Serif");
00626 m_Font.CreateFontIndirect(&lf);
00627
00628
00629 m_ListRowsArray = new CCustomListRowWnd*[CCustomList::MAXROWS];
00630 for(INT32 i=0; i<CCustomList::MAXROWS; i++)
00631 {
00632 m_ListRowsArray[i] = NULL;
00633 }
00634
00635
00636 WNDCLASS NewWindowClass;
00637 memset(&NewWindowClass, 0, sizeof(WNDCLASS));
00638 NewWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
00639 NewWindowClass.lpfnWndProc = ::DefWindowProc;
00640 NewWindowClass.hInstance = AfxGetInstanceHandle();
00641 NewWindowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); ;
00642 NewWindowClass.lpszMenuName = NULL;
00643 NewWindowClass.lpszClassName = _T("RowClass");
00644 AfxRegisterClass(&NewWindowClass);
00645 }
00646
00647
00648 CCustomListScrollableArea::~CCustomListScrollableArea()
00649 {
00650 delete m_ListRowsArray;
00651 m_ListRowsArray = NULL;
00652 }
00653
00654
00655 void CCustomListScrollableArea::PostNcDestroy()
00656 {
00657 delete this;
00658 CWnd::PostNcDestroy();
00659 }
00660
00661
00662
00663 void CCustomListScrollableArea::HandleScrollMessage(UINT32 nSBCode, UINT32 nPos )
00664 {
00665 SCROLLINFO si;
00666 si.cbSize = sizeof(SCROLLINFO);
00667 si.fMask = SIF_TRACKPOS|SIF_PAGE|SIF_RANGE;
00668 m_Parent->GetVScrollBar()->GetScrollInfo(&si);
00669
00670 INT32 NewPos = m_ScrollPos ;
00671 switch(nSBCode)
00672 {
00673 case SB_PAGEDOWN:
00674 NewPos = m_ScrollPos + si.nPage;
00675 break ;
00676 case SB_PAGEUP:
00677 NewPos = m_ScrollPos - si.nPage;
00678 break ;
00679 case SB_LINEDOWN:
00680 NewPos = m_ScrollPos + CCustomList::ROWHEIGHT;
00681 break ;
00682 case SB_LINEUP:
00683 NewPos = m_ScrollPos - CCustomList::ROWHEIGHT;
00684 break ;
00685 case SB_THUMBTRACK:
00686 case SB_THUMBPOSITION:
00687 NewPos = nPos;
00688 break;
00689 }
00690 INT32 LastPos = si.nMax-si.nPage + 1 ;
00691
00692 if( NewPos < 0 )
00693 NewPos = 0;
00694 if( NewPos > LastPos )
00695 NewPos = LastPos ;
00696
00697 INT32 offset = m_ScrollPos - NewPos;
00698 this->ScrollWindow(0,offset);
00699 m_ScrollPos = NewPos;
00700 m_Parent->GetVScrollBar()->SetScrollPos(m_ScrollPos , true);
00701 }
00702
00703
00704 CCustomListRowWnd* CCustomListScrollableArea::GetRow(INT32 row)
00705 {
00706 ASSERT(row < m_RowCount);
00707 return m_ListRowsArray[row] ;
00708 }
00709
00710
00711
00712
00713
00714
00715 void CCustomListScrollableArea::SelectRow(INT32 RowNum)
00716 {
00717 if( m_CurrentSelectedRow > -1 )
00718 {
00719 m_ListRowsArray[m_CurrentSelectedRow]->m_Selected = false ;
00720 m_ListRowsArray[m_CurrentSelectedRow]->RedrawWindow();
00721 }
00722 m_CurrentSelectedRow = RowNum;
00723
00724 if( m_CurrentSelectedRow > -1 && this->IsWindowEnabled())
00725 {
00726
00727 CRect parentRect;
00728 m_Parent->GetClientRect(&parentRect);
00729 INT32 Page = parentRect.Height();
00730 if((m_CurrentSelectedRow) * CCustomList::ROWHEIGHT < m_ScrollPos)
00731 {
00732 HandleScrollMessage(SB_THUMBPOSITION,m_CurrentSelectedRow * CCustomList::ROWHEIGHT);
00733 }
00734 else if((m_CurrentSelectedRow+1) * CCustomList::ROWHEIGHT > (m_ScrollPos + Page))
00735 {
00736 HandleScrollMessage(SB_THUMBPOSITION,(m_CurrentSelectedRow+1) * CCustomList::ROWHEIGHT - Page);
00737 }
00738
00739 ASSERT(m_ListRowsArray!=NULL);
00740 m_ListRowsArray[m_CurrentSelectedRow]->m_Selected = true ;
00741 m_ListRowsArray[m_CurrentSelectedRow]->RedrawWindow();
00742 m_ListRowsArray[m_CurrentSelectedRow]->SetFocus();
00743 }
00744 }
00745
00746
00747 void CCustomListScrollableArea::OnSize(UINT32 nType, INT32 cx, INT32 cy)
00748 {
00749 ASSERT( GetHeight() == cy );
00750 CWnd::OnSize(nType, cx, cy);
00751
00752 CRect parentRect;
00753 m_Parent->GetClientRect(parentRect);
00754
00755
00756 SCROLLINFO si;
00757 si.cbSize = sizeof(SCROLLINFO);
00758 si.fMask = SIF_PAGE|SIF_RANGE;
00759 si.nPage = (INT32)parentRect.Height();
00760 si.nMin = 0;
00761 si.nMax = GetHeight();
00762 m_Parent->m_VScrollBar->SetScrollInfo(&si, true);
00763 }
00764
00765
00769
00770
00771
00775
00776 BEGIN_MESSAGE_MAP(CCustomListRowWnd, CWnd)
00777
00778 ON_WM_LBUTTONUP()
00779 ON_WM_ERASEBKGND()
00780 ON_WM_CTLCOLOR()
00781 ON_WM_LBUTTONDBLCLK()
00782 ON_WM_KEYDOWN()
00783 ON_WM_GETDLGCODE()
00784 ON_WM_DESTROY()
00785
00786 END_MESSAGE_MAP()
00787
00788 CCustomListRowWnd::CCustomListRowWnd(INT32 RowNo, CCustomListScrollableArea* parent) :
00789 m_BackBrush(RGB(255,255,255)) ,
00790 m_BackBrushSel(::GetSysColor (COLOR_HIGHLIGHT)),
00791 m_Selected(false),
00792 m_RowNum(RowNo),
00793 m_Parent(parent)
00794 {
00795
00796
00797 m_ColumnObjects = new CObject* [CCustomList::MAXCOLUMNS];
00798 for( INT32 i=0; i < CCustomList::MAXCOLUMNS; i++)
00799 m_ColumnObjects[i] = NULL;
00800 }
00801
00802 CCustomListRowWnd::~CCustomListRowWnd()
00803 {
00804
00805 for( INT32 i=0; i < CCustomList::MAXCOLUMNS; i++)
00806 {
00807 if ( m_ColumnObjects[i] !=NULL )
00808 {
00809 delete m_ColumnObjects[i];
00810 m_ColumnObjects[i] = NULL;
00811 }
00812 }
00813 delete m_ColumnObjects ;
00814 }
00815
00816
00817 void CCustomListRowWnd::PostNcDestroy()
00818 {
00819 delete this;
00820 CWnd::PostNcDestroy();
00821 }
00822
00823
00824
00825 void CCustomListRowWnd::OnDestroy()
00826 {
00827 CWnd::OnDestroy();
00828 for( INT32 i=0; i < CCustomList::MAXCOLUMNS; i++)
00829 {
00830 if ( m_ColumnObjects[i] !=NULL )
00831 {
00832 if( m_ColumnObjects[i]->IsKindOf(RUNTIME_CLASS(CStatic)) )
00833 {
00834 if( ((CStatic*)m_ColumnObjects[i])->GetSafeHwnd() )
00835 {
00836 HBITMAP hBitmap = ((CStatic*)m_ColumnObjects[i])->GetBitmap();
00837 if(hBitmap)
00838 {
00839 ::DeleteObject(hBitmap);
00840 }
00841 }
00842 }
00843 }
00844 }
00845 }
00846
00847
00848 void CCustomListRowWnd::AddCheck(INT32 col)
00849 {
00850 CButton* pBut = new CButton();
00851 m_ColumnObjects[col] = pBut ;
00852
00853 CRect cr;
00854 GetClientRect(&cr);
00855 ASSERT(cr.Height() == CCustomList::ROWHEIGHT);
00856
00857 CRect rect;
00858 rect.left = m_Parent->m_Parent->m_ColumnOffsetsArray[col] ;
00859 rect.right = rect.left + GetSystemMetrics(SM_CXMENUCHECK);
00860 rect.top = (CCustomList::ROWHEIGHT - GetSystemMetrics(SM_CYMENUCHECK))/2;
00861 rect.bottom = rect.top + GetSystemMetrics(SM_CYMENUCHECK) ;
00862 pBut->Create(NULL, WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, rect, this, 4);
00863 }
00864
00865
00866 void CCustomListRowWnd::SetChecked(INT32 col, BOOL checked)
00867 {
00868 ASSERT(m_ColumnObjects[col] != NULL );
00869 ASSERT(m_ColumnObjects[col]->IsKindOf(RUNTIME_CLASS( CButton)));
00870
00871 CButton* pBut = (CButton*)m_ColumnObjects[col];
00872 pBut->SetCheck(checked ? BST_CHECKED : BST_UNCHECKED );
00873 pBut->UpdateWindow();
00874 }
00875
00876
00877 bool CCustomListRowWnd::IsChecked(INT32 col) const
00878 {
00879 CButton* pBut = (CButton*)m_ColumnObjects[col];
00880 return pBut->GetCheck() == BST_CHECKED;
00881 }
00882
00883
00884
00885 void CCustomListRowWnd::OnLButtonUp(UINT32 nFlags, CPoint point)
00886 {
00887 CWnd::OnLButtonUp(nFlags, point);
00888 m_Parent->SelectRow(m_RowNum);
00889 CWnd::OnLButtonUp(nFlags, point);
00890 }
00891
00892
00893 BOOL CCustomListRowWnd::OnEraseBkgnd(CDC* pDC)
00894 {
00895 CBrush* pOldBrush = pDC->SelectObject(m_Selected ? &m_BackBrushSel : &m_BackBrush);
00896
00897 CRect rect;
00898 pDC->GetClipBox(&rect);
00899
00900 pDC->PatBlt(rect.left,rect.top,rect.Width(),rect.Height(),PATCOPY);
00901 pDC->SelectObject(pOldBrush);
00902
00903 return true;
00904 }
00905
00906
00907 void CCustomListRowWnd::AddText(INT32 col, CString text)
00908 {
00909 ASSERT(m_ColumnObjects[col] == NULL);
00910
00911 CStatic* pStat = new CStatic();
00912 m_ColumnObjects[col] = pStat ;
00913
00914 CRect cr;
00915 GetClientRect(&cr);
00916
00917 CRect srect;
00918 srect.left= m_Parent->m_Parent->m_ColumnOffsetsArray[col] ;
00919 if( col < CCustomList::MAXCOLUMNS && m_Parent->m_Parent->m_ColumnOffsetsArray[col + 1] > 0)
00920 srect.right= m_Parent->m_Parent->m_ColumnOffsetsArray[col + 1] ;
00921 else
00922 srect.right= cr.right;
00923 srect.top = (CCustomList::ROWHEIGHT - CCustomList::FONTHEIGHT)/2;
00924 srect.bottom = srect.top + CCustomList::FONTHEIGHT;
00925 pStat->Create(text, WS_CHILD|WS_VISIBLE|WS_EX_LEFT, srect, this);
00926 pStat->SetFont(&m_Parent->m_Font);
00927 }
00928
00929
00930 void CCustomListRowWnd::SetText(INT32 col, CString text)
00931 {
00932 CStatic* pStat = (CStatic*)m_ColumnObjects[col];
00933 if( pStat == NULL )
00934 AddText(col,text);
00935 else
00936 {
00937 pStat->SetWindowText(text);
00938 pStat->UpdateWindow();
00939 }
00940 }
00941
00942
00943 void CCustomListRowWnd::AddBitmap(INT32 col, HBITMAP hBitmap,HBITMAP, DWORD dwBackColour)
00944 {
00945 CStatic* pStat = new CStatic();
00946 ASSERT(m_ColumnObjects[col] == NULL);
00947 m_ColumnObjects[col] = pStat ;
00948
00949 CRect cr;
00950 GetClientRect(&cr);
00951
00952 BITMAP bitmap;
00953 CBitmap::FromHandle(hBitmap)->GetBitmap(&bitmap);
00954 CRect srect;
00955 srect.left = m_Parent->m_Parent->m_ColumnOffsetsArray[col] ;
00956 srect.right = srect.left + bitmap.bmWidth;
00957 srect.top = cr.Height()/2 - bitmap.bmHeight/2;
00958 srect.bottom = cr.Height()/2 + bitmap.bmHeight/2;
00959
00961 HDC hBitmapDC = CreateCompatibleDC(NULL);
00962 if (!hBitmapDC)
00963 {
00964 ERROR2RAW("Non-fatal GDI error");
00965 }
00966 SelectObject(hBitmapDC, hBitmap);
00967
00968
00969 if (dwBackColour == 0xFFFFFFFF)
00970 dwBackColour = (DWORD) GetPixel(hBitmapDC, bitmap.bmWidth - 1, bitmap.bmHeight -1);
00971 DWORD sysBkColour = GetSysColor(COLOR_3DFACE);
00972 for (INT32 i = 0; i < bitmap.bmWidth; i++)
00973 {
00974 for (INT32 j = 0; j < bitmap.bmHeight; j++)
00975 {
00976 if ((DWORD) GetPixel(hBitmapDC, i, j) == dwBackColour)
00977 SetPixelV(hBitmapDC, i, j, (COLORREF) sysBkColour);
00978 }
00979 }
00980 DeleteDC(hBitmapDC);
00981
00983 pStat->Create(NULL, WS_VISIBLE | SS_BITMAP, srect, this);
00984 pStat->SetBitmap(hBitmap);
00985 }
00986
00987
00988
00989 HBRUSH CCustomListRowWnd::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT32 nCtlColor)
00990 {
00991 HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor);
00992 COLORREF text = m_Selected ? GetSysColor(COLOR_HIGHLIGHTTEXT) : GetSysColor(COLOR_WINDOWTEXT);
00993 pDC->SetTextColor(text);
00994 pDC->SetBkMode(TRANSPARENT);
00995
00996 return GetBackgroundBrush();
00997 }
00998
00999
01000
01001 void CCustomListRowWnd::OnLButtonDblClk(UINT32 nFlags, CPoint point)
01002 {
01003 m_Parent->SelectRow(m_RowNum);
01004 CWnd* caller = m_Parent->m_Parent->GetOwner();
01005 INT32 ControlID = m_Parent->m_Parent->GetDlgCtrlID();
01006 if(caller && ControlID )
01007 {
01008 NMHDR nm;
01009 nm.hwndFrom = m_Parent->m_Parent->m_hWnd;
01010 nm.idFrom = ControlID;
01011 nm.code = NM_DBLCLK;
01012
01013 ::SendMessage(caller->m_hWnd ,WM_NOTIFY,ControlID , (LPARAM)&nm );
01014 }
01015 }
01016
01017
01018 CString CCustomListRowWnd::GetText(INT32 col) const
01019 {
01020 CStatic* pStat = (CStatic*)m_ColumnObjects[col];
01021 CString ret ;
01022 pStat->GetWindowText(ret);
01023 return ret;
01024 }
01025
01026
01027 void CCustomListRowWnd::OnKeyDown(UINT32 nChar, UINT32 nRepCnt, UINT32 nFlags)
01028 {
01029 if(nChar == CAMKEY(DOWN) && m_RowNum + 1 < m_Parent->m_RowCount)
01030 m_Parent->SelectRow(m_RowNum+1);
01031 else if(nChar == CAMKEY(UP) && m_RowNum - 1 >= 0)
01032 m_Parent->SelectRow(m_RowNum-1);
01033
01034 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
01035 }
01036
01037
01038 UINT32 CCustomListRowWnd::OnGetDlgCode()
01039 {
01040 UINT32 uRet = CWnd::OnGetDlgCode();
01041 uRet |= DLGC_WANTARROWS;
01042 return uRet;
01043 }
01044
01045
01046
01047 BOOL CCustomListRowWnd::OnCommand(WPARAM wParam, LPARAM lParam)
01048 {
01049 UINT32 nID = LOWORD(wParam);
01050 HWND hWndCtrl = (HWND)lParam;
01051 INT32 nCode = HIWORD(wParam);
01053 m_Parent->SelectRow(m_RowNum);
01054 CWnd* caller = m_Parent->m_Parent->GetOwner();
01055 INT32 ControlID = m_Parent->m_Parent->GetDlgCtrlID();
01056 if(caller && ControlID )
01057 {
01058 NMHDR nm;
01059 nm.hwndFrom = m_hWnd;
01060 nm.idFrom = ControlID;
01061 nm.code = NULL;
01062
01063 ::SendMessage(caller->m_hWnd ,WM_NOTIFY, ControlID , (LPARAM)&nm);
01064 }
01065 return CWnd::OnCommand(wParam, lParam);
01066 }
01067
01068
01069
01070
01071 CCustomListRowWnd* CCustomListScrollableArea::AddRow()
01072 {
01073 CCustomListRowWnd* pRow = new CCustomListRowWnd(m_RowCount,this);
01074 ASSERT(pRow);
01075 m_ListRowsArray[m_RowCount] = pRow;
01076 m_RowCount++;
01077
01078 CRect parentRect;
01079 m_Parent->GetClientRect(&parentRect);
01080
01081 CRect rect ;
01082 rect.top = (m_RowCount-1) * CCustomList::ROWHEIGHT ;
01083 rect.left = 0 ;
01084 rect.bottom = 0 + (m_RowCount) * CCustomList::ROWHEIGHT ;
01085 rect.right = parentRect.right - 1;
01086
01087 pRow->Create("RowClass","",WS_CHILD,rect,this,0);
01088 pRow->ShowWindow(SW_SHOW);
01089
01090
01091 BOOL needScroll = GetHeight() > parentRect.Height();
01092 INT32 width = parentRect.right;
01093 if(needScroll)
01094 width=width - ::GetSystemMetrics(SM_CXVSCROLL);
01095 m_Parent->m_VScrollBar->ShowWindow(needScroll ? SW_SHOW : SW_HIDE);
01096 SetWindowPos(NULL,0,0,width,GetHeight(),0);
01097
01098 return pRow;
01099 }
01100
01101
01102
01103
01104 BOOL CCustomList::OnMouseWheel(UINT32 nFlags, short zDelta, CPoint pt)
01105 {
01106 SCROLLINFO si;
01107 si.cbSize = sizeof(SCROLLINFO);
01108 si.fMask = SIF_TRACKPOS|SIF_PAGE|SIF_RANGE;
01109 GetVScrollBar()->GetScrollInfo(&si);
01110
01111 INT32 nStep = GetKeyState(CAMKEY(CONTROL))<0 ? si.nPage : ROWHEIGHT ;
01112
01113 INT32 newPos = GetVScrollBar()->GetScrollPos() - nStep*zDelta/WHEEL_DELTA;
01114
01115
01116 if(newPos < ROWHEIGHT)
01117 newPos = 0;
01118
01119 if(newPos > si.nMax)
01120 newPos = si.nMax;
01121
01122 if (m_ScrollableArea)
01123 {
01124 m_ScrollableArea->HandleScrollMessage(SB_THUMBPOSITION, newPos);
01125 }
01126 return CWnd::OnMouseWheel(nFlags, zDelta, pt);
01127 }
01128