1 //####COPYRIGHTBEGIN####
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6 // This program is part of the eCos host tools.
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // ----------------------------------------------------------------------------
24 //####COPYRIGHTEND####
25 // MLTView.cpp: implementation of the CMLTView class.
27 //////////////////////////////////////////////////////////////////////
33 #include "ConfigtoolDoc.h"
35 #include "ConfigTool.h"
42 static char THIS_FILE[] = __FILE__;
47 //////////////////////////////////////////////////////////////////////
48 // Construction/Destruction
49 //////////////////////////////////////////////////////////////////////
51 IMPLEMENT_DYNCREATE(CMLTView, CScrollView)
53 BEGIN_MESSAGE_MAP(CMLTView, CScrollView)
54 //{{AFX_MSG_MAP(CMLTView)
60 ON_COMMAND(ID_EDIT_NEW_REGION, OnMLTNewRegion)
61 ON_COMMAND(ID_EDIT_NEW_SECTION, OnMLTNewSection)
62 ON_COMMAND(ID_EDIT_DELETE_SECTION, OnMLTDelete)
63 ON_COMMAND(ID_EDIT_PROPERTIES, OnMLTProperties)
64 ON_UPDATE_COMMAND_UI(ID_EDIT_NEW_SECTION, OnUpdateMLTNewSection)
65 ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE_SECTION, OnUpdateMLTDelete)
66 ON_UPDATE_COMMAND_UI(ID_EDIT_PROPERTIES, OnUpdateMLTProperties)
68 ON_COMMAND(ID_POPUP_PROPERTIES, OnPopupProperties)
74 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
75 ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
76 // Standard printing commands
77 ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
78 ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
79 ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
86 CConfigTool::SetMLTView(this);
91 CConfigTool::SetMLTView(0);
92 for(POSITION pos = m_arstrTooltipRects.GetStartPosition(); pos != NULL; ){
95 m_arstrTooltipRects.GetNextAssoc( pos, strName, (void *&)pRect );
100 /////////////////////////////////////////////////////////////////////////////
103 #define VERT_BORDER 30 /* the vertical border at the top/bottom of the client area */
104 #define HORIZ_BORDER 30 /* the horizontal border at the left/right of the client area */
105 #define BAR_HEIGHT 18 /* the height of the memory section caption bar */
106 #define MAP_HEIGHT 66 /* the height of each memory section rectangle (including caption bar) */
107 #define REGION_SPACING 115 /* the vertical offset between successive memory regions */
108 #define ADDRESS_TEXT_SPACE 0.9 /* use 90% of the section width to draw the address */
109 #define EXTERNAL_TEXT_BORDER 5 /* spacing between external text and border of region */
110 #define ADDRESS_FORMAT _T("%08X") /* draw memory addresses in hex format */
111 #define UNITS_PER_SECTION 3 /* memory section width in units, unused sections are 1 unit wide */
112 #define UNIT_WIDTH_MIN 27 /* minimum width of memory section unit before horizontal scrolling enabled */
113 #define TICK_HEIGHT 4 /* the height of the tick marks on the memory sections and regions */
115 #define DISPLAY_MODE 1 /* 1 == const unit width for all regions */
116 /* 2 == const region width for all regions */
118 void CMLTView::OnDraw(CDC* pDC)
120 CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
121 if (pDoc == NULL) // no document so nothing to draw
124 // clear the lists of region and section rectangles used for hit testing
126 listRegionRect.RemoveAll ();
127 listSectionRect.RemoveAll ();
129 // setup background mode
131 int nOldBkMode = pDC->SetBkMode (TRANSPARENT);
136 if (!fntName.CreatePointFont (80, _T("MS Sans Serif"), pDC))
138 CFont * pOldFont = pDC->SelectObject (&fntName);
140 // determine max unit count for any region
142 mem_map * pMemoryMap = &CConfigTool::GetConfigToolDoc()->MemoryMap;
144 // calculate the unit scaling for DISPLAY_MODE 1
146 UINT uPixelsPerUnit = UNIT_WIDTH_MIN;
148 if (m_uUnitCountMax != 0) // if there is something to draw
151 GetClientRect (&rectClientRect);
152 uPixelsPerUnit = __max ((m_uClientWidth - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN);
153 m_uViewWidth = uPixelsPerUnit * m_uUnitCountMax + HORIZ_BORDER * 2;
160 list <mem_region>::iterator region;
161 for (region = pMemoryMap->region_list.begin (); region != pMemoryMap->region_list.end (); ++region)
164 for (list <mem_section_view>::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view)
165 uUnitCount += (section_view->section == NULL ? 1 : UNITS_PER_SECTION);
167 if (DISPLAY_MODE == 1)
168 DrawRegion (pDC, uRegion++, uUnitCount, uPixelsPerUnit, region);
169 else // DISPLAY_MODE == 2
170 DrawRegion (pDC, uRegion++, uUnitCount, (rectClientRect.right - HORIZ_BORDER * 2) / uUnitCount, region);
173 pDC->SelectObject (pOldFont);
174 pDC->SetBkMode (nOldBkMode);
178 void CMLTView::DrawRegion (CDC* pDC, UINT uRegion, UINT uUnitCount, UINT uPixelsPerUnit, list <mem_region>::iterator region)
180 BOOL bDrawFocusRect = FALSE;
184 // setup the drawing objects
186 CBrush brshUnusedSection;
187 if (!brshUnusedSection.CreateHatchBrush (HS_BDIAGONAL, RGB (128, 128, 128)))
190 CBrush brshUsedSection;
191 if (!brshUsedSection.CreateSolidBrush (GetSysColor (COLOR_WINDOW)))
194 CBrush brshInitialSectionBar;
195 if (!brshInitialSectionBar.CreateSolidBrush (GetSysColor (COLOR_INACTIVECAPTION)))
198 CBrush brshFixedSectionBar;
199 if (!brshFixedSectionBar.CreateSolidBrush (GetSysColor (COLOR_ACTIVECAPTION)))
202 CBrush brshFinalSectionBar;
203 if (!brshFinalSectionBar.CreateSolidBrush (GetSysColor (COLOR_ACTIVECAPTION)))
207 if (!penBorder.CreatePen (PS_SOLID, 1, GetSysColor (COLOR_WINDOWTEXT)))
211 if (!penSelected.CreatePen (PS_SOLID, 2, GetSysColor (COLOR_WINDOWTEXT)))
214 // select the border pen object
216 CPen * pOldPen = pDC->SelectObject (&penBorder);
218 // calculate the region rectangle
221 srRegion.Rect.SetRect (HORIZ_BORDER, VERT_BORDER + REGION_SPACING * uRegion, HORIZ_BORDER + uUnitCount * uPixelsPerUnit + 1, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + 1);
222 srRegion.Region = region;
223 listRegionRect.AddTail (srRegion);
227 CPoint pointOrigin (srRegion.Rect.left, srRegion.Rect.top);
228 pDC->LPtoDP (&pointOrigin);
231 pDC->SetBrushOrg (pointOrigin);
232 CBrush * pOldBrush = pDC->SelectObject (&brshUnusedSection);
233 pDC->Rectangle (srRegion.Rect);
235 pDC->MoveTo (srRegion.Rect.left, srRegion.Rect.bottom - 1); // draw tick
236 pDC->LineTo (srRegion.Rect.left, srRegion.Rect.bottom + TICK_HEIGHT); // draw tick
238 if (region == m_riSelectedRegion)
240 bDrawFocusRect = TRUE;
241 m_rectSelectedItem = srRegion.Rect;
244 // draw the region label
246 CRect rectRegionLabel (HORIZ_BORDER, VERT_BORDER + REGION_SPACING * uRegion - EXTERNAL_TEXT_BORDER - 20, m_uViewWidth - HORIZ_BORDER /*HORIZ_BORDER + uUnitCount * uPixelsPerUnit + 1*/, VERT_BORDER + REGION_SPACING * uRegion - EXTERNAL_TEXT_BORDER);
247 CString strRegionLabel;
248 strRegionLabel.Format (_T("%s (%08X-%08X)%s"), CString(region->name.c_str ()), region->address, region->address + region->size - 1, ((region->type == read_only) ? _T(" read only") : _T("")));
249 pDC->DrawText (strRegionLabel, -1, rectRegionLabel, DT_BOTTOM | DT_SINGLELINE);
251 // draw the start address of the region
253 rectAddress.SetRect (HORIZ_BORDER, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + ADDRESS_TEXT_SPACE * UNITS_PER_SECTION * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30);
254 strAddress.Format (ADDRESS_FORMAT, region->address);
255 pDC->DrawText (strAddress, -1, rectAddress, DT_LEFT | DT_SINGLELINE);
257 // draw the end address of the region
259 rectAddress.SetRect (HORIZ_BORDER + (uUnitCount - ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + (uUnitCount + ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30);
260 strAddress.Format (ADDRESS_FORMAT, region->address + region->size);
261 pDC->DrawText (strAddress, -1, rectAddress, DT_CENTER | DT_SINGLELINE);
263 // draw the sections within the region
265 UINT uSectionUnitCount = 0;
267 SECTIONRECT srSection;
268 for (list <mem_section_view>::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view)
270 if (section_view->section != NULL) // the section is used
274 pDC->SelectObject (brshUsedSection);
275 srSection.Rect.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION) * uPixelsPerUnit + 1, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + 1);
276 srSection.SectionView = section_view;
277 listSectionRect.AddTail (srSection);
278 pDC->Rectangle (srSection.Rect);
279 if (section_view == m_sviSelectedSectionView)
281 bDrawFocusRect = TRUE;
282 m_rectSelectedItem = srSection.Rect;
285 // draw text within the section
287 CString strSection, strSectionLine;
289 if ((section_view->section_location != initial_location) && (section_view->section->alignment > 1))
291 strSectionLine.Format (_T("align %lX\n"), section_view->section->alignment);
292 strSection += strSectionLine;
295 if (section_view->section->size > 0)
297 strSectionLine.Format (_T("size %lX\n"), section_view->section->size);
298 strSection += strSectionLine;
301 if (section_view->section_location == final_location)
303 strSectionLine.Format (_T("relocated\n"));
304 strSection += strSectionLine;
307 pDC->DrawText (strSection, -1, srSection.Rect - (LPCRECT) CRect (EXTERNAL_TEXT_BORDER, EXTERNAL_TEXT_BORDER + BAR_HEIGHT, EXTERNAL_TEXT_BORDER, EXTERNAL_TEXT_BORDER), DT_LEFT);
309 // select caption bar colour according to type of section
311 if (section_view->section_location == initial_location)
313 pDC->SetTextColor (GetSysColor (COLOR_INACTIVECAPTIONTEXT));
314 pDC->SelectObject (&brshInitialSectionBar);
318 pDC->SetTextColor (GetSysColor (COLOR_CAPTIONTEXT));
319 pDC->SelectObject (&brshFinalSectionBar);
322 // draw the caption bar
324 rectBar.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION) * uPixelsPerUnit + 1, VERT_BORDER + REGION_SPACING * uRegion + BAR_HEIGHT + 1);
325 pDC->Rectangle (rectBar);
327 // draw the section name within the caption bar
329 CString strName(section_view->section->name.c_str ());
331 m_arstrTooltipRects.Lookup(strName,(void *&)pRect);
333 if(pDC->GetTextExtent(strName).cx>rectBar.Width()-2*EXTERNAL_TEXT_BORDER){
336 pRect->CopyRect(rectBar);
339 m_arstrTooltipRects.SetAt(strName,pRect);
341 // Replace final three characters of name with an elipsis
342 int nLength=1+max(1,strName.GetLength()-3);
345 strName=strName.Left(nLength)+_T("...");
346 } while(nLength>1 && pDC->GetTextExtent(strName).cx>rectBar.Width()-2*EXTERNAL_TEXT_BORDER);
348 rectBar.left+=EXTERNAL_TEXT_BORDER;
349 rectBar.right-=EXTERNAL_TEXT_BORDER;
353 m_arstrTooltipRects.RemoveKey(strName);
357 pDC->DrawText (strName, -1, rectBar, format | DT_VCENTER | DT_SINGLELINE);
358 pDC->SetTextColor (GetSysColor (COLOR_WINDOWTEXT));
360 // find the mem_section item describing the current section_view item
362 list <mem_section>::iterator MemorySection = section_view->section;
364 // draw the section address if appropriate
366 if ((section_view->section_location == initial_location))
368 if (MemorySection->initial_location->anchor == absolute)
370 pDC->MoveTo (srSection.Rect.left, srSection.Rect.bottom - 1); // draw tick
371 pDC->LineTo (srSection.Rect.left, srSection.Rect.bottom + TICK_HEIGHT); // draw tick
372 rectAddress.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, (int) (HORIZ_BORDER + (uSectionUnitCount + ADDRESS_TEXT_SPACE * UNITS_PER_SECTION) * uPixelsPerUnit), VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30);
373 strAddress.Format (ADDRESS_FORMAT, MemorySection->initial_location->address);
374 pDC->DrawText (strAddress, -1, rectAddress, DT_LEFT | DT_SINGLELINE);
377 if (MemorySection->size > 0) // the end address can be calculated
379 rectAddress.SetRect (HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION - ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION + ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30);
380 strAddress.Format (ADDRESS_FORMAT, MemorySection->initial_location->address + MemorySection->size);
381 pDC->DrawText (strAddress, -1, rectAddress, DT_CENTER | DT_SINGLELINE);
387 else if ((section_view->section_location == final_location) || (section_view->section_location == fixed_location))
389 if (MemorySection->final_location->anchor == absolute)
391 pDC->MoveTo (srSection.Rect.left, srSection.Rect.bottom - 1); // draw tick
392 pDC->LineTo (srSection.Rect.left, srSection.Rect.bottom + TICK_HEIGHT); // draw tick
393 rectAddress.SetRect (HORIZ_BORDER + uSectionUnitCount * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, (int) (HORIZ_BORDER + (uSectionUnitCount + ADDRESS_TEXT_SPACE * UNITS_PER_SECTION) * uPixelsPerUnit), VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30);
394 strAddress.Format (ADDRESS_FORMAT, MemorySection->final_location->address);
395 pDC->DrawText (strAddress, -1, rectAddress, DT_LEFT | DT_SINGLELINE);
398 if (MemorySection->size > 0) // the end address can be calculated
400 rectAddress.SetRect (HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION - ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER, HORIZ_BORDER + (uSectionUnitCount + UNITS_PER_SECTION + ADDRESS_TEXT_SPACE) * uPixelsPerUnit, VERT_BORDER + REGION_SPACING * uRegion + MAP_HEIGHT + EXTERNAL_TEXT_BORDER + 30);
401 strAddress.Format (ADDRESS_FORMAT, MemorySection->final_location->address + MemorySection->size);
402 pDC->DrawText (strAddress, -1, rectAddress, DT_CENTER | DT_SINGLELINE);
408 uSectionUnitCount += UNITS_PER_SECTION;
412 uSectionUnitCount++; // unused sections occupy a single unit
416 // draw the focus rectangle around the selected object (if any)
419 pDC->DrawFocusRect (m_rectSelectedItem + CRect (1, 1, 1, 1));
421 // restore previous drawing objects
423 pDC->SelectObject (pOldBrush);
424 pDC->SelectObject (pOldPen);
428 SECTIONRECT * CMLTView::SectionHitTest (CPoint pntTest)
430 for (POSITION posSection = listSectionRect.GetHeadPosition (); posSection != NULL; listSectionRect.GetNext (posSection))
432 if (listSectionRect.GetAt (posSection).Rect.PtInRect (pntTest))
433 return & listSectionRect.GetAt (posSection);
440 REGIONRECT * CMLTView::RegionHitTest (CPoint pntTest)
442 for (POSITION posRegion = listRegionRect.GetHeadPosition (); posRegion != NULL; listRegionRect.GetNext (posRegion))
444 CRect rectRegion = listRegionRect.GetAt (posRegion).Rect +
445 CRect (EXTERNAL_TEXT_BORDER + 20, EXTERNAL_TEXT_BORDER + 20, EXTERNAL_TEXT_BORDER + 20, EXTERNAL_TEXT_BORDER + 20); // extended rectangle to allow clicking on region label
446 if (rectRegion.PtInRect (pntTest))
447 return & listRegionRect.GetAt (posRegion);
454 /////////////////////////////////////////////////////////////////////////////
457 BOOL CMLTView::OnPreparePrinting(CPrintInfo* pInfo)
459 // default preparation
460 return DoPreparePrinting(pInfo);
463 void CMLTView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
465 // TODO: add extra initialization before printing
468 void CMLTView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
470 // TODO: add cleanup after printing
473 /////////////////////////////////////////////////////////////////////////////
474 // CMLTView diagnostics
477 void CMLTView::AssertValid() const
479 CView::AssertValid();
482 void CMLTView::Dump(CDumpContext& dc) const
489 /////////////////////////////////////////////////////////////////////////////
490 // CMLTView message handlers
493 void CMLTView::OnLButtonDown(UINT nFlags, CPoint point)
495 if (CConfigTool::GetConfigToolDoc() == NULL) // nothing to do
498 list <mem_section_view>::iterator sviOldSelectedSectionView = m_sviSelectedSectionView;
499 list <mem_region>::iterator riOldSelectedRegion = m_riSelectedRegion;
500 CRect rectOldSelectedItem = m_rectSelectedItem;
502 CConfigTool::GetConfigToolDoc()->strSelectedRegion = _T("");
503 CConfigTool::GetConfigToolDoc()->strSelectedSection = _T("");
505 SECTIONRECT * psrSection = SectionHitTest (point + GetScrollPosition ());
506 if (psrSection != NULL) // a section was clicked
508 m_sviSelectedSectionView = psrSection->SectionView;
509 m_rectSelectedItem = psrSection->Rect;
510 m_riSelectedRegion = NULL;
511 CConfigTool::GetConfigToolDoc()->strSelectedSection = m_sviSelectedSectionView->section->name.c_str ();
514 else // no section was clicked, test for regions
516 REGIONRECT * prrRegion = RegionHitTest (point + GetScrollPosition ());
517 if (prrRegion != NULL) // a region was clicked, but not a section
519 m_riSelectedRegion = prrRegion->Region;
520 m_rectSelectedItem = prrRegion->Rect;
521 m_sviSelectedSectionView = NULL;
522 CConfigTool::GetConfigToolDoc()->strSelectedRegion = m_riSelectedRegion->name.c_str ();
526 // redraw the focus rectangle if the selection has changed
528 if ((m_sviSelectedSectionView != sviOldSelectedSectionView) || (m_riSelectedRegion != riOldSelectedRegion))
530 // CDC * pDC = GetDC ();
531 if ((sviOldSelectedSectionView != NULL) || (riOldSelectedRegion != NULL))
532 // pDC->DrawFocusRect (rectOldSelectedItem + CRect (1, 1, 1, 1) - GetScrollPosition ());
533 InvalidateRect (rectOldSelectedItem + CRect (1, 1, 1, 1) - GetScrollPosition ()); // paint over the old focus rectangle
534 if ((m_sviSelectedSectionView != NULL) || (m_riSelectedRegion != NULL))
535 // pDC->DrawFocusRect (m_rectSelectedItem + CRect (1, 1, 1, 1) - GetScrollPosition ());
536 InvalidateRect (m_rectSelectedItem + CRect (1, 1, 1, 1) - GetScrollPosition ()); // paint the new focus rectangle
539 // perform default processing
541 CView::OnLButtonDown(nFlags, point);
544 void CMLTView::OnLButtonDblClk(UINT nFlags, CPoint point)
546 if (CConfigTool::GetConfigToolDoc() != NULL)
547 CConfigTool::GetConfigToolDoc()->OnMLTProperties ();
549 CView::OnLButtonDblClk(nFlags, point);
552 void CMLTView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
554 if ((lHint != 0) && (pHint != NULL) && (lHint != CConfigToolDoc::MemLayoutChanged))
555 return; // no need to invalidate the view
556 m_arstrTooltipRects.RemoveAll();
558 CalcUnitCountMax (); // recalculate the total view width since the section count may have changed
559 if (m_uUnitCountMax == 0 || (m_uClientWidth < HORIZ_BORDER * 2)) // there is nothing to draw
561 else // allow horizontal scrolling when the unit width reduces to UNIT_WIDTH_MIN
562 m_uViewWidth = __max ((m_uClientWidth - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN) * m_uUnitCountMax + HORIZ_BORDER * 2;
565 sizeTotal.cx = __max (m_uViewWidth, m_uClientWidth);
566 sizeTotal.cy = CConfigTool::GetConfigToolDoc()->MemoryMap.region_list.size () * REGION_SPACING + EXTERNAL_TEXT_BORDER * 2;
567 SetScrollSizes (MM_TEXT, sizeTotal);
569 CScrollView::OnUpdate (pSender, lHint, pHint);
572 void CMLTView::OnSize(UINT nType, int cx, int cy)
574 CScrollView::OnSize(nType, cx, cy);
577 if (m_uUnitCountMax == 0) // there is nothing to draw
579 else // allow horizontal scrolling when the unit width reduces to UNIT_WIDTH_MIN
580 m_uViewWidth = __max ((cx - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN) * m_uUnitCountMax + HORIZ_BORDER * 2;
583 sizeTotal.cx = __max (m_uViewWidth, m_uClientWidth);
584 if (CConfigTool::GetConfigToolDoc() == NULL)
587 sizeTotal.cy = CConfigTool::GetConfigToolDoc()->MemoryMap.region_list.size () * REGION_SPACING + EXTERNAL_TEXT_BORDER * 2;
588 SetScrollSizes (MM_TEXT, sizeTotal);
591 void CMLTView::CalcUnitCountMax ()
593 UINT uUnitCountMax = 0;
595 list <mem_region>::iterator region;
596 mem_map * pMemoryMap = & (CConfigTool::GetConfigToolDoc()->MemoryMap);
597 for (region = pMemoryMap->region_list.begin (); region != pMemoryMap->region_list.end (); ++region)
600 for (list <mem_section_view>::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view)
601 uUnitCount += (section_view->section == NULL ? 1 : UNITS_PER_SECTION);
603 if (uUnitCount > uUnitCountMax)
604 uUnitCountMax = uUnitCount;
606 m_uUnitCountMax = uUnitCountMax;
609 BOOL CMLTView::OnEraseBkgnd(CDC* pDC)
611 // Work around bug apparently caused by SlickEdit
613 pDC->GetClipBox(rcClient);
614 pDC->FillSolidRect(rcClient,GetSysColor(COLOR_WINDOW));
616 return TRUE;//return CScrollView::OnEraseBkgnd(pDC);
619 BOOL CMLTView::OnToolTipText(UINT id, NMHDR* pNMHDR, LRESULT*pResult)
621 // need to handle both ANSI and UNICODE versions of the message
622 TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
623 TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
627 for(POSITION pos = m_arstrTooltipRects.GetStartPosition(); pos != NULL; ){
630 m_arstrTooltipRects.GetNextAssoc( pos, strTipText, (void *&)pRect );
633 if (pNMHDR->code == TTN_NEEDTEXTA)
634 lstrcpyn(pTTTA->szText, strTipText, sizeof pTTTA->szText/sizeof TCHAR - 1);
636 _mbstowcsz(pTTTW->szText, strTipText, sizeof pTTTW->szText/sizeof TCHAR - 1);
638 if (pNMHDR->code == TTN_NEEDTEXTA)
639 _wcstombsz(pTTTA->szText, strTipText, sizeof pTTTA->szText/sizeof TCHAR - 1);
641 lstrcpyn(pTTTW->szText, strTipText, sizeof pTTTW->szText/sizeof TCHAR - 1);
644 return TRUE; // message was handled
651 int CMLTView::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const
653 for(POSITION pos = m_arstrTooltipRects.GetStartPosition(); pos != NULL; ){
656 m_arstrTooltipRects.GetNextAssoc( pos, strName, (void *&)pRect );
658 if(pRect->PtInRect(point)){
660 pTI->uId = (UINT)pRect;
662 GetClientRect(&pTI->rect);
663 pTI->lpszText=LPSTR_TEXTCALLBACK;
670 void CMLTView::OnInitialUpdate()
672 CScrollView::OnInitialUpdate();
673 EnableToolTips(true);
676 void CMLTView::OnMouseMove(UINT nFlags, CPoint point)
679 CString strToolTipText;
680 for(POSITION pos = m_arstrTooltipRects.GetStartPosition(); pos != NULL; ){
683 m_arstrTooltipRects.GetNextAssoc( pos, strName, (void *&)pRect );
685 if(pRect->PtInRect(point)){
686 strToolTipText=strName;
690 if(strToolTipText!=m_strTipText){
691 _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
692 CToolTipCtrl* pToolTip = pThreadState->m_pToolTip;
693 if(!m_strTipText.IsEmpty()){
694 pToolTip->Activate(false);
696 pToolTip->Activate(!strToolTipText.IsEmpty());
697 m_strTipText=strToolTipText;
700 CScrollView::OnMouseMove(nFlags, point);
703 void CMLTView::OnMLTNewRegion ()
705 CConfigTool::GetConfigToolDoc ()->OnMLTNewRegion ();
708 void CMLTView::OnMLTNewSection ()
710 CConfigTool::GetConfigToolDoc ()->OnMLTNewSection ();
713 void CMLTView::OnMLTDelete ()
715 CConfigTool::GetConfigToolDoc ()->OnMLTDelete ();
718 void CMLTView::OnMLTProperties ()
720 CConfigTool::GetConfigToolDoc ()->OnMLTProperties ();
723 void CMLTView::OnUpdateMLTNewRegion (CCmdUI* pCmdUI)
725 pCmdUI->Enable (true);
728 void CMLTView::OnUpdateMLTNewSection (CCmdUI* pCmdUI)
730 pCmdUI->Enable (CConfigTool::GetConfigToolDoc()->MemoryMap.region_list.size() > 0);
733 void CMLTView::OnUpdateMLTDelete (CCmdUI* pCmdUI)
736 (!CConfigTool::GetConfigToolDoc ()->strSelectedRegion.IsEmpty() || !CConfigTool::GetConfigToolDoc ()->strSelectedSection.IsEmpty()));
739 void CMLTView::OnUpdateMLTProperties (CCmdUI* pCmdUI)
742 (!CConfigTool::GetConfigToolDoc ()->strSelectedRegion.IsEmpty() || !CConfigTool::GetConfigToolDoc ()->strSelectedSection.IsEmpty()));
746 void CMLTView::OnContextMenu(CWnd*, CPoint point)
748 CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
749 if (!pDoc->strSelectedRegion.IsEmpty() || !pDoc->strSelectedSection.IsEmpty()){
752 point=!pDoc->strSelectedRegion.IsEmpty()?m_rectSelectedItem.TopLeft():m_rectSelectedItem.CenterPoint();
753 ClientToScreen(&point);
756 menu.LoadMenu(IDR_MLTVIEW_POPUP);
759 menu.LoadToolbar(IDR_MISCBAR);
762 Menu *pPopup=(Menu *)menu.GetSubMenu(0);
763 pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, point.x,point.y,this);
767 void CMLTView::OnPopupProperties()
769 CConfigTool::GetConfigToolDoc()->OnMLTProperties ();
772 void CMLTView::OnRButtonDown(UINT nFlags, CPoint point)
774 OnLButtonDown(nFlags, point);
775 ClientToScreen(&point);
776 OnContextMenu(this, point) ;
779 void CMLTView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
784 pos = listSectionRect.GetHeadPosition ();
785 if(!CConfigTool::GetConfigToolDoc()->strSelectedSection.IsEmpty()){
787 if (listSectionRect.GetNext (pos).SectionView==m_sviSelectedSectionView){
789 pos=listSectionRect.GetHeadPosition();
795 OnLButtonDown(0, listSectionRect.GetNext(pos).Rect.CenterPoint()-GetScrollPosition());
798 pos = listSectionRect.GetTailPosition ();
799 if(!CConfigTool::GetConfigToolDoc()->strSelectedSection.IsEmpty()){
801 if (listSectionRect.GetPrev (pos).SectionView==m_sviSelectedSectionView){
803 pos=listSectionRect.GetTailPosition();
809 OnLButtonDown(0, listSectionRect.GetPrev(pos).Rect.CenterPoint()-GetScrollPosition());
812 pos = listRegionRect.GetHeadPosition ();
813 if(!CConfigTool::GetConfigToolDoc()->strSelectedRegion.IsEmpty()){
815 if (listRegionRect.GetNext (pos).Region==m_riSelectedRegion){
817 pos=listRegionRect.GetHeadPosition();
823 OnLButtonDown(0, listRegionRect.GetNext(pos).Rect.TopLeft()-CPoint(1,1)-GetScrollPosition());
826 pos = listRegionRect.GetTailPosition ();
827 if(!CConfigTool::GetConfigToolDoc()->strSelectedRegion.IsEmpty()){
829 if (listRegionRect.GetPrev (pos).Region==m_riSelectedRegion){
831 pos=listRegionRect.GetTailPosition();
837 OnLButtonDown(0, listRegionRect.GetPrev(pos).Rect.TopLeft()-CPoint(1,1)-GetScrollPosition());
843 CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
847 BOOL CMLTView::OnHelpInfo(HELPINFO*)
849 return CConfigTool::GetConfigToolDoc()->ShowURL(CUtils::LoadString(IDS_MLT_VIEW_HELP));
852 LRESULT CMLTView::OnMenuChar(UINT, UINT, CMenu*)
854 const MSG *pMsg=GetCurrentMessage();
855 // punt to the mainframe to deal with shortcuts in popups
856 return AfxGetMainWnd()->SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam);