コード例 #1
0
ファイル: RenderMapWindowBg.cpp プロジェクト: Turbo87/LK8000
void MapWindow::RenderMapWindowBg(HDC hdc, const RECT rc,
				  const POINT &Orig,
				  const POINT &Orig_Aircraft)
{

  // Calculations are taking time and slow down painting of map, beware
  #define MULTICALC_MINROBIN	5	// minimum split
  #define MULTICALC_MAXROBIN	20	// max split
  static short multicalc_slot=0;// -1 (which becomes immediately 0) will force full loading on startup, but this is not good
				// because currently we are not waiting for ProgramStarted=3
				// and the first scan is made while still initializing other things

  // TODO assign numslots with a function, based also on available CPU time
  short numslots=1;
  #if NEWSMARTZOOM
  static double quickdrawscale=0.0;
  static double delta_drawscale=1.0;
  #endif

  #if 0 
  extern void TestChangeRect();
  TestChangeRect();
  #endif

  if ((MapWindow::AlphaBlendSupported() && BarOpacity<100) || mode.AnyPan()) {
	MapWindow::ChangeDrawRect(MapRect);
  } else {
	RECT newRect={0,0,ScreenSizeX,ScreenSizeY-BottomSize};
	MapWindow::ChangeDrawRect(newRect);
  }

  if (QUICKDRAW) {
	goto _skip_calcs;
  }

  if (NumberOfWayPoints>200) {
	numslots=NumberOfWayPoints/400;
	// keep numslots optimal
	if (numslots<MULTICALC_MINROBIN) numslots=MULTICALC_MINROBIN; // seconds for full scan, as this is executed at 1Hz
	if (numslots>MULTICALC_MAXROBIN) numslots=MULTICALC_MAXROBIN;

	// When waypointnumber has changed, we wont be using an exceeded multicalc_slot, which would crash the sw
	// In this case, we shall probably continue for the first round to calculate without going from the beginning
	// but this is not a problem, we are round-robin all the time here.
	if (++multicalc_slot>numslots) multicalc_slot=1;
  } else {
	multicalc_slot=0; // forcing full scan
  }

  // Here we calculate arrival altitude, GD etc for map waypoints. Splitting with multicalc will result in delayed
  // updating of visible landables, for example. The nearest pages do this separately, with their own sorting.
  // Basically we assume -like for nearest- that values will not change that much in the multicalc split time.
  // Target and tasks are recalculated in real time in any case. Nearest too. 
  LKCalculateWaypointReachable(multicalc_slot, numslots);

_skip_calcs:
  CalculateScreenPositionsAirspace(rc);

  CalculateScreenPositionsThermalSources();

  // Make the glide amoeba out of the latlon points, converting them to screen
  // (This function is updated for supporting multimaps )
  CalculateScreenPositionsGroundline();

  if (PGZoomTrigger) {
    if(!mode.Is(Mode::MODE_PANORAMA)) {
      mode.Special(Mode::MODE_SPECIAL_PANORAMA, true);
		LastZoomTrigger=DrawInfo.Time;
      
		Message::Lock();
	        Message::AddMessage(1000, 3, gettext(TEXT("_@M872_"))); // LANDSCAPE ZOOM FOR 20s
		Message::Unlock();
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) LKSound(TEXT("LK_TONEUP.WAV"));
		#endif
    }
    else {
		// previously called, see if time has passed
		if ( DrawInfo.Time > (LastZoomTrigger + 20.0)) {
			// time has passed, lets go back
			LastZoomTrigger=0; // just for safety
        mode.Special(Mode::MODE_SPECIAL_PANORAMA, false);
			PGZoomTrigger=false;
			Message::Lock(); 
	        	Message::AddMessage(1500, 3, gettext(TEXT("_@M873_"))); // BACK TO NORMAL ZOOM
			Message::Unlock();
			#ifndef DISABLEAUDIO
			if (EnableSoundModes) LKSound(TEXT("LK_TONEDOWN.WAV"));
			#endif
		}
	}
  }

  // 
  // "Checkpoint Charlie"
  // This is were we process stuff for anything else but main map.
  // We let the calculations run also for MapSpace modes.
  // But for multimaps, we can also draw some more stuff..
  // We are also sent back here from next code, when we detect that
  // the MapSpace mode has changed from MAP to something else while we
  // were rendering.
  //
QuickRedraw:
  //
  if (DONTDRAWTHEMAP) 
  {
	DrawMapSpace(hdc, rc);
	// Is this a "shared map" environment? 
	if (IsMultiMapShared()) { 
		// Shared map, of course not MSN_MAP, since dontdrawthemap was checked
		//
		if (IsMultimapOverlaysText()) {
			DrawLook8000(hdc,rc);
		}
		if (IsMultimapOverlaysGauges()) {
			if (LKVarioBar) LKDrawVario(hdc,rc);

			if ((mode.Is(Mode::MODE_CIRCLING)) )
				if (ThermalBar) DrawThermalBand(hdcDrawWindow, rc);

			DrawFinalGlide(hdcDrawWindow,rc);
		}

	} else {
		// Not in map painting environment 
		// ex. nearest pages, but also MAPRADAR..
	}

	// 
	DrawBottomBar(hdc,rc);
#ifdef CPUSTATS
	DrawCpuStats(hdc,rc);
#endif
#ifdef DRAWDEBUG
	DrawDebug(hdc,rc);
#endif
	// no need to do SelectObject as at the bottom of function
	return;
  }

  // When no terrain is painted, set a background0
  // Remember that in this case we have plenty of cpu time to spend for best result
  if (!IsMultimapTerrain() || !DerivedDrawInfo.TerrainValid || !RasterTerrain::isTerrainLoaded() ) {

    // display border and fill background..
	SelectObject(hdc, hInvBackgroundBrush[BgMapColor]);
	SelectObject(hdc, GetStockObject(WHITE_PEN));

	Rectangle(hdc,rc.left,rc.top,rc.right,rc.bottom);
	// We force LK painting black values on screen depending on the background color in use
	// TODO make it an array once settled
	// blackscreen would force everything to be painted white, instead
	LKTextBlack=BgMapColorTextBlack[BgMapColor];
	if (BgMapColor>6 ) BlackScreen=true; else BlackScreen=false; 
  } else {
	LKTextBlack=false;
	BlackScreen=false;
  }

  #if NEWSMARTZOOM
  // Copy the old background map with no overlays
  if (ONSMARTZOOM) {

	if (quickdrawscale>0) {
		delta_drawscale=zoom.DrawScale() / quickdrawscale;
	}

// StartupStore(_T("... QuickDrawScale=%.2f new zoom=%.2f  delta=%.2f\n"),quickdrawscale,zoom.DrawScale(),delta_drawscale);

	int dx=MapRect.right-MapRect.left;
	int dy=MapRect.bottom-MapRect.top;

	// notice: zoom in is always ok.. but zoom out starting from high zoom levels will make the picture
	// very small and unusable. We can consider to zoom out in fast zoom normally, in such cases?
	//
	// Notice 2: the delta is not yet working correctly 
	//
	if (delta_drawscale>1.0) {
		// zoom in
		StretchBlt(hdcDrawWindow, 
			0,0,
			dx,dy, 
			hdcQuickDrawWindow,
			(int)((dx/2) - (dx / delta_drawscale)/2),
			(int)((dy/2) - (dy / delta_drawscale)/2),
			(int)(dx / delta_drawscale),
			(int)(dy / delta_drawscale), 
			SRCCOPY);
	} else {
		// zoom out
		StretchBlt(hdcDrawWindow,
			(int)((dx/2) - (dx * delta_drawscale)/2),
			(int)((dy/2) - (dy * delta_drawscale)/2),
			(int)(dx * delta_drawscale),
			(int)(dy * delta_drawscale), 
			hdcQuickDrawWindow,
			0,0,
			dx,dy,  
			SRCCOPY);
	}
  }
  #endif


  // Logic of DONTDRAWTHEMAP is the following:
  // We are rendering the screen page here. If we are here, we passed Checkpoint Charlie.
  // So we were, at charlie, in MSM_MAP: preparing the main map stuff.
  // If we detect that MapSpace has CHANGED while we were doing our job here,
  // it means that the user has clicked meanwhile. He desires another page, so let's
  // reset our intentions and go back to beginning, or nearby..
  // We have a new job to do, for another MapSpace, no more MAP.
  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  #if NEWSMARTZOOM
  if ( OFFSMARTZOOM ) {
  #endif

  bool terrainpainted=false;

  if ((IsMultimapTerrain() && (DerivedDrawInfo.TerrainValid) 
       && RasterTerrain::isTerrainLoaded())
	) {
	// sunelevation is never used, it is still a todo in Terrain
	double sunelevation = 40.0;
	double sunazimuth=GetAzimuth();

    LockTerrainDataGraphics();
 	if (DONTDRAWTHEMAP) { // 100318
		UnlockTerrainDataGraphics();
		goto QuickRedraw;
	}
    DrawTerrain(hdc, DrawRect, sunazimuth, sunelevation);
    terrainpainted=true;
 	if (DONTDRAWTHEMAP) {
		UnlockTerrainDataGraphics();
		goto QuickRedraw;
	}
    if (!QUICKDRAW) {
    	// SHADED terrain unreachable, aka glide amoeba. This is not the outlined perimeter!
        #ifdef GTL2
    	if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) && 
            DerivedDrawInfo.TerrainValid) {
        #else
    	if ((FinalGlideTerrain==2) && DerivedDrawInfo.TerrainValid) {
        #endif
    	  DrawTerrainAbove(hdc, DrawRect);
    	}
    }
    UnlockTerrainDataGraphics();
  }

  #if NEWSMARTZOOM
  }
  #endif

  //
  // REMINDER: WE ARE IN MAIN MAP HERE: MSM_MAP ONLY, OR PANNING MODE!
  // MAPSPACEMODE CAN STILL CHANGE, DUE TO USER INPUT. BUT WE GOT HERE IN
  // EITHER PAN OR MSM_MAP.
  //

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  if (IsMultimapTopology()) {
    DrawTopology(hdc, DrawRect);
  } else {
	// If no topology wanted, but terrain painted, we paint only water stuff
	if (terrainpainted) DrawTopology(hdc, DrawRect,true);
  }
  #if 0
  StartupStore(_T("... Experimental1=%.0f\n"),Experimental1);
  StartupStore(_T("... Experimental2=%.0f\n"),Experimental2);
  Experimental1=0.0;
  Experimental2=0.0;
  #endif

  // Topology labels are printed first, using OLD wps positions from previous run!
  // Reset for topology labels decluttering engine occurs also in another place here!
  ResetLabelDeclutter();
  
  if (Flags_DrawTask && ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
	DrawTaskAAT(hdc, DrawRect);
  }

  
  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  if (IsMultimapAirspace())
  {
    if ( (GetAirSpaceFillType() == asp_fill_ablend_full) || (GetAirSpaceFillType() == asp_fill_ablend_borders) )
      DrawTptAirSpace(hdc, rc);
    else
      DrawAirSpace(hdc, rc);	 // full screen, to hide clipping effect on low border
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  // In QUICKDRAW dont draw trail, thermals, glide terrain
  if (QUICKDRAW) goto _skip_stuff;
 
  if(TrailActive) {
	// NEED REWRITING
	LKDrawTrail(hdc, Orig_Aircraft, DrawRect);
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  DrawThermalEstimate(hdc, DrawRect);
  if (OvertargetMode==OVT_THER) DrawThermalEstimateMultitarget(hdc, DrawRect);
 
  // draw red cross on glide through terrain marker
  if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid) {
    DrawGlideThroughTerrain(hdc, DrawRect);
  }
  
  if (DONTDRAWTHEMAP) { 
	goto QuickRedraw;
  }

_skip_stuff:

  if (IsMultimapAirspace() && AirspaceWarningMapLabels)
  {
	DrawAirspaceLabels(hdc, DrawRect, Orig_Aircraft);
	if (DONTDRAWTHEMAP) { // 100319
		goto QuickRedraw;
	}
  }

  if (IsMultimapWaypoints()) {
	DrawWaypointsNew(hdc,DrawRect);
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  if (Flags_DrawTask && ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) {
	DrawTask(hdc, DrawRect, Orig_Aircraft);
  }

  // FAI optimizer does not depend on tasks, being based on trace
  if (Flags_DrawFAI)  DrawFAIOptimizer(hdc, DrawRect, Orig_Aircraft);

  // In QUICKDRAW do not paint other useless stuff
  if (QUICKDRAW) {
	if (extGPSCONNECT) DrawBearing(hdc, DrawRect);
	goto _skip_2;
  }

  // ---------------------------------------------------

  DrawTeammate(hdc, rc);

  if (extGPSCONNECT) {
    DrawBestCruiseTrack(hdc, Orig_Aircraft);
    DrawBearing(hdc, DrawRect);
  }

  // draw wind vector at aircraft
  if (NOTANYPAN) {
    DrawWindAtAircraft2(hdc, Orig_Aircraft, DrawRect);
  } else if (mode.Is(Mode::MODE_TARGET_PAN)) {
    DrawWindAtAircraft2(hdc, Orig, rc);
  }

  #if NEWSMARTZOOM
  // Save the current rendered map before painting overlays
  if ( OFFSMARTZOOM ) {
	quickdrawscale=zoom.DrawScale();
	BitBlt(hdcQuickDrawWindow, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top,
		hdcDrawWindow, 0, 0, SRCCOPY);
  }
  #endif

  // VisualGlide drawn BEFORE lk8000 overlays
  if (NOTANYPAN && (VisualGlide > 0)) {
    DrawGlideCircle(hdc, Orig, rc); 
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }

  // Draw traffic and other specifix LK gauges
  LKDrawFLARMTraffic(hdc, DrawRect, Orig_Aircraft);

  // ---------------------------------------------------
_skip_2:

  if (NOTANYPAN) {
    // REMINDER TODO let it be configurable for not circling also, as before
    if ((mode.Is(Mode::MODE_CIRCLING)) )
      if (ThermalBar) DrawThermalBand(hdcDrawWindow, rc); // 091122
  
    if (IsMultimapOverlaysText()) DrawLook8000(hdc,rc); 
    DrawBottomBar(hdc,rc);
  }

  if (DONTDRAWTHEMAP) {
	goto QuickRedraw;
  }
    
  if (IsMultimapOverlaysGauges() && (LKVarioBar && NOTANYPAN)) 
	LKDrawVario(hdc,rc);
  
  // Draw glider or paraglider
  if (extGPSCONNECT) {
    DrawAircraft(hdc, Orig_Aircraft);
  }

  if (NOTANYPAN && !QUICKDRAW) {
	if (TrackBar) DrawHeading(hdc, Orig, DrawRect); 
  }

  #if USETOPOMARKS
  // marks on top...
  DrawMarks(hdc, rc);
  #endif

  if (ISGAAIRCRAFT && IsMultimapOverlaysGauges() && NOTANYPAN) DrawHSI(hdc,Orig,DrawRect); 

  if (!INPAN) {
	DrawMapScale(hdcDrawWindow,rc, zoom.BigZoom()); // unused BigZoom
	DrawCompass(hdcDrawWindow, rc, DisplayAngle);
  }

  if (IsMultimapOverlaysGauges() && NOTANYPAN) DrawFinalGlide(hdcDrawWindow,rc);


#ifdef CPUSTATS
  DrawCpuStats(hdc,rc);
#endif
#ifdef DRAWDEBUG
  DrawDebug(hdc,rc);
#endif

}
コード例 #2
0
void MapWindow::RenderMapWindowBg(HDC hdc, const RECT rc,
				  const POINT &Orig,
				  const POINT &Orig_Aircraft)
{
  HFONT hfOld;

  // Calculations are taking time and slow down painting of map, beware
  #define MULTICALC_MINROBIN	5	// minimum split
  #define MULTICALC_MAXROBIN	20	// max split
  static short multicalc_slot=0;// -1 (which becomes immediately 0) will force full loading on startup, but this is not good
				// because currently we are not waiting for ProgramStarted=3
				// and the first scan is made while still initializing other things

  // TODO assign numslots with a function, based also on available CPU time
  short numslots=1;
  #if NEWSMARTZOOM
  static double quickdrawscale=0.0;
  static double delta_drawscale=1.0;
  #endif

  // If we have a BigZoom request, we serve it immediately without calculating anything
  // TODO: stretch the old map bitmap to the new zoom, while fastzooming
  if (QUICKDRAW) {
	goto fastzoom;
  }

  if (NumberOfWayPoints>200) {
	numslots=NumberOfWayPoints/400;
	// keep numslots optimal
	if (numslots<MULTICALC_MINROBIN) numslots=MULTICALC_MINROBIN; // seconds for full scan, as this is executed at 1Hz
	if (numslots>MULTICALC_MAXROBIN) numslots=MULTICALC_MAXROBIN;

	// When waypointnumber has changed, we wont be using an exceeded multicalc_slot, which would crash the sw
	// In this case, we shall probably continue for the first round to calculate without going from the beginning
	// but this is not a problem, we are round-robin all the time here.
	if (++multicalc_slot>numslots) multicalc_slot=1;
  } else {
	multicalc_slot=0; // forcing full scan
  }

  // Here we calculate arrival altitude, GD etc for map waypoints. Splitting with multicalc will result in delayed
  // updating of visible landables, for example. The nearest pages do this separately, with their own sorting.
  // Basically we assume -like for nearest- that values will not change that much in the multicalc split time.
  // Target and tasks are recalculated in real time in any case. Nearest too. 
  LKCalculateWaypointReachable(multicalc_slot, numslots);
  CalculateScreenPositionsAirspace();
  CalculateScreenPositionsThermalSources();
  CalculateScreenPositionsGroundline();

  if (PGZoomTrigger) {
    if(!mode.Is(Mode::MODE_PANORAMA)) {
      mode.Special(Mode::MODE_SPECIAL_PANORAMA, true);
		LastZoomTrigger=GPS_INFO.Time;
      
		Message::Lock();
	        Message::AddMessage(1000, 3, gettext(TEXT("_@M872_"))); // LANDSCAPE ZOOM FOR 20s
		Message::Unlock();
		#ifndef DISABLEAUDIO
		if (EnableSoundModes) LKSound(TEXT("LK_TONEUP.WAV"));
		#endif
    }
    else {
		// previously called, see if time has passed
		if ( GPS_INFO.Time > (LastZoomTrigger + 20.0)) {
			// time has passed, lets go back
			LastZoomTrigger=0; // just for safety
        mode.Special(Mode::MODE_SPECIAL_PANORAMA, false);
			PGZoomTrigger=false;
			Message::Lock(); 
	        	Message::AddMessage(1500, 3, gettext(TEXT("_@M873_"))); // BACK TO NORMAL ZOOM
			Message::Unlock();
			#ifndef DISABLEAUDIO
			if (EnableSoundModes) LKSound(TEXT("LK_TONEDOWN.WAV"));
			#endif
		}
	}
  }
	
  // let the calculations run, but dont draw anything but the look8000 when in MapSpaceMode != MSM_MAP
  if (DONTDRAWTHEMAP) 
  {
QuickRedraw: // 100318 speedup redraw
	DrawLook8000(hdc,rc);
#ifdef CPUSTATS
	DrawCpuStats(hdc,rc);
#endif
#ifdef DRAWDEBUG
	DrawDebug(hdc,rc);
#endif
	// no need to do SelectObject as at the bottom of function
	return;
  }

  // When no terrain is painted, set a background0
  // Remember that in this case we have plenty of cpu time to spend for best result
  if (!EnableTerrain || !DerivedDrawInfo.TerrainValid || !RasterTerrain::isTerrainLoaded() ) {

    // display border and fill background..
	SelectObject(hdc, hInvBackgroundBrush[BgMapColor]);
	SelectObject(hdc, GetStockObject(WHITE_PEN));

	Rectangle(hdc,rc.left,rc.top,rc.right,rc.bottom);
	// We force LK painting black values on screen depending on the background color in use
	// TODO make it an array once settled
	// blackscreen would force everything to be painted white, instead
	LKTextBlack=BgMapColorTextBlack[BgMapColor];
	if (BgMapColor>6 ) BlackScreen=true; else BlackScreen=false; 
  } else {
	LKTextBlack=false;
	BlackScreen=false;
  }

fastzoom:  

  #if NEWSMARTZOOM
  // Copy the old background map with no overlays
  if (ONSMARTZOOM) {

	if (quickdrawscale>0) {
		delta_drawscale=zoom.DrawScale() / quickdrawscale;
	}

// StartupStore(_T("... QuickDrawScale=%.2f new zoom=%.2f  delta=%.2f\n"),quickdrawscale,zoom.DrawScale(),delta_drawscale);

	int dx=MapRect.right-MapRect.left;
	int dy=MapRect.bottom-MapRect.top;

	// notice: zoom in is always ok.. but zoom out starting from high zoom levels will make the picture
	// very small and unusable. We can consider to zoom out in fast zoom normally, in such cases?
	//
	// Notice 2: the delta is not yet working correctly 
	//
	if (delta_drawscale>1.0) {
		// zoom in
		StretchBlt(hdcDrawWindow, 
			0,0,
			dx,dy, 
			hdcQuickDrawWindow,
			(int)((dx/2) - (dx / delta_drawscale)/2),
			(int)((dy/2) - (dy / delta_drawscale)/2),
			(int)(dx / delta_drawscale),
			(int)(dy / delta_drawscale), 
			SRCCOPY);
	} else {
		// zoom out
		StretchBlt(hdcDrawWindow,
			(int)((dx/2) - (dx * delta_drawscale)/2),
			(int)((dy/2) - (dy * delta_drawscale)/2),
			(int)(dx * delta_drawscale),
			(int)(dy * delta_drawscale), 
			hdcQuickDrawWindow,
			0,0,
			dx,dy,  
			SRCCOPY);
	}
  }
  #endif

  SelectObject(hdc, GetStockObject(BLACK_BRUSH));
  SelectObject(hdc, GetStockObject(BLACK_PEN));
  hfOld = (HFONT)SelectObject(hdc, MapWindowFont);
  
  // ground first...
  
  if (DONTDRAWTHEMAP) { // 100319
	SelectObject(hdcDrawWindow, hfOld);
	goto QuickRedraw;
  }

  #if NEWSMARTZOOM
  if ( OFFSMARTZOOM ) {
  #endif

  if ((EnableTerrain && (DerivedDrawInfo.TerrainValid) 
       && RasterTerrain::isTerrainLoaded())
	) {
	// sunelevation is never used, it is still a todo in Terrain
	double sunelevation = 40.0;
	double sunazimuth=GetAzimuth();

    LockTerrainDataGraphics();
 	if (DONTDRAWTHEMAP) { // 100318
		UnlockTerrainDataGraphics();
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}
    DrawTerrain(hdc, rc, sunazimuth, sunelevation); // LOCKED 091105
 	if (DONTDRAWTHEMAP) { // 100318
		UnlockTerrainDataGraphics();
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}
    if (!QUICKDRAW) {
    	// shaded terrain unreachable, aka glide amoeba
        #ifdef GTL2
    	if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) && 
            DerivedDrawInfo.TerrainValid) {
        #else
    	if ((FinalGlideTerrain==2) && DerivedDrawInfo.TerrainValid) {
        #endif
    	  DrawTerrainAbove(hdc, rc);
    	}
    }
    UnlockTerrainDataGraphics();
  }

  #if NEWSMARTZOOM
  }
  #endif

  if (QUICKDRAW)  {
	if ( !mode.AnyPan()) DrawLook8000(hdc,rc); 
  	SelectObject(hdcDrawWindow, hfOld);
	return;
  }

  if (DONTDRAWTHEMAP) { // 100319
	SelectObject(hdcDrawWindow, hfOld);
	goto QuickRedraw;
  }

  if (EnableTopology) {
    DrawTopology(hdc, rc); // LOCKED 091105
  }
  #if 0
  StartupStore(_T("... Experimental1=%.0f\n"),Experimental1);
  StartupStore(_T("... Experimental2=%.0f\n"),Experimental2);
  Experimental1=0.0;
  Experimental2=0.0;
  #endif

  // Topology labels are printed first, using OLD wps positions from previous run!
  // Reset for topology labels decluttering engine occurs also in another place here!

  nLabelBlocks = 0;
  #if TOPOFASTLABEL
  for (short nvi=0; nvi<SCREENVSLOTS; nvi++) nVLabelBlocks[nvi]=0;
  #endif
  
  if (ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) { // 100503
	DrawTaskAAT(hdc, rc);
  }

  
 	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}
 
  if (OnAirSpace > 0)  // Default is true, always true at startup no regsave 
  {
    if ( (GetAirSpaceFillType() == asp_fill_ablend_full) || (GetAirSpaceFillType() == asp_fill_ablend_borders) )
      DrawTptAirSpace(hdc, rc);
    else
      DrawAirSpace(hdc, rc);
  }

 	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}
  
  if(TrailActive) {
	// NEED REWRITING
	LKDrawTrail(hdc, Orig_Aircraft, rc);
  }

 	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}

  DrawThermalEstimate(hdc, rc);
  if (OvertargetMode==OVT_THER) DrawThermalEstimateMultitarget(hdc, rc);
 
  // draw red cross on glide through terrain marker
  if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid) {
    DrawGlideThroughTerrain(hdc, rc);
  }
  
 	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}
  if ((OnAirSpace > 0) && AirspaceWarningMapLabels)
  {
	DrawAirspaceLabels(hdc, rc, Orig_Aircraft);
	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}
  }
  DrawWaypointsNew(hdc,rc);
 	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}

  if (ValidTaskPoint(ActiveWayPoint) && ValidTaskPoint(1)) { // 100503
	DrawTask(hdc, rc, Orig_Aircraft);
  }
  DrawTeammate(hdc, rc);

  if (extGPSCONNECT) {
    DrawBestCruiseTrack(hdc, Orig_Aircraft);
    DrawBearing(hdc, rc);
  }

  // draw wind vector at aircraft
  if (!mode.AnyPan()) {
    DrawWindAtAircraft2(hdc, Orig_Aircraft, rc);
  } else if (mode.Is(Mode::MODE_TARGET_PAN)) {
    DrawWindAtAircraft2(hdc, Orig, rc);
  }

  #if NEWSMARTZOOM
  // Save the current rendered map before painting overlays
  if ( OFFSMARTZOOM ) {
	quickdrawscale=zoom.DrawScale();
	BitBlt(hdcQuickDrawWindow, 0, 0, MapRect.right-MapRect.left, MapRect.bottom-MapRect.top,
		hdcDrawWindow, 0, 0, SRCCOPY);
  }
  #endif

  // VisualGlide drawn BEFORE lk8000 overlays
  if (!mode.AnyPan() && VisualGlide > 0) {
    DrawGlideCircle(hdc, Orig, rc); 
  }

 	if (DONTDRAWTHEMAP) { // 100319
		SelectObject(hdcDrawWindow, hfOld);
		goto QuickRedraw;
	}

  // Draw traffic and other specifix LK gauges
  	LKDrawFLARMTraffic(hdc, rc, Orig_Aircraft);

  if (!mode.AnyPan()) {
    // REMINDER TODO let it be configurable for not circling also, as before
    if ((mode.Is(Mode::MODE_CIRCLING)) )
      if (ThermalBar) DrawThermalBand(hdcDrawWindow, rc); // 091122
    
    DrawLook8000(hdc,rc); 
  }
    
	if (LKVarioBar && !mode.AnyPan()) // 091214 do not draw Vario when in Pan mode
		LKDrawVario(hdc,rc); // 091111
  
  // Draw glider or paraglider
  if (extGPSCONNECT) {
    DrawAircraft(hdc, Orig_Aircraft);
  }

  if (!mode.AnyPan()) {
	if (TrackBar) DrawHeading(hdc, Orig, rc); 
  }

  #if USETOPOMARKS
  // marks on top...
  DrawMarks(hdc, rc);
  #endif

  if (ISGAAIRCRAFT) DrawHSI(hdc,Orig,rc); 

#ifdef CPUSTATS
  DrawCpuStats(hdc,rc);
#endif
#ifdef DRAWDEBUG
  DrawDebug(hdc,rc);
#endif

  SelectObject(hdcDrawWindow, hfOld);

}
コード例 #3
0
void MapWindow::DrawInfoPage(HDC hdc,  RECT rc, bool forceinit )
{
  HFONT		oldfont=0;
  //SIZE TextSize;
  TCHAR Buffer[LKSIZEBUFFERLARGE];
  TCHAR BufferTitle[LKSIZEBUFFERTITLE];
  TCHAR BufferValue[LKSIZEBUFFERVALUE];
  TCHAR BufferUnit[LKSIZEBUFFERUNIT];
  TCHAR Empty[2]; // 100407
  int index=-1;

  static short	column[PANELCOLUMNS+1], hcolumn[(PANELCOLUMNS*2)+1], qcolumn[(PANELCOLUMNS*4)+1];
  static short	row[PANELROWS+1], hrow[(PANELCOLUMNS*2)+1], qrow[(PANELROWS*4)+1];

  bool showunit=false;
  _tcscpy(Empty,_T(""));

  if (forceinit) DoInit[MDI_DRAWINFOPAGE]=true;

	oldfont = (HFONT)SelectObject(hdc, LKINFOFONT); // save font

  if (DoInit[MDI_DRAWINFOPAGE]) {
	DoInit[MDI_DRAWINFOPAGE]=false;
	// function can only be called in fullscreen  and thus can be inited here
	column[0]=LEFTLIMITER;
	column[1]=((rc.right-RIGHTLIMITER-LEFTLIMITER)/PANELCOLUMNS)+LEFTLIMITER;
	column[2]=column[1]*2-LEFTLIMITER;
	column[3]=column[1]*3-LEFTLIMITER*2;
	column[PANELCOLUMNS]=rc.right-RIGHTLIMITER;
	row[0]=rc.top+TOPLIMITER;
	row[1]=((rc.bottom-BottomSize-row[0]-BOTTOMLIMITER)/PANELROWS)+row[0];
	row[2]=((rc.bottom-BottomSize-row[0]-BOTTOMLIMITER)/PANELROWS)*2+row[0];
	row[3]=((rc.bottom-BottomSize-row[0]-BOTTOMLIMITER)/PANELROWS)*3+row[0];
	row[PANELROWS]=rc.bottom-BottomSize-BOTTOMLIMITER;

	hcolumn[0]=column[0];
	hcolumn[1]=(column[1]-column[0])/2;
	hcolumn[2]=column[1];
	hcolumn[3]=(column[2]-column[1])/2+column[1];
	hcolumn[4]=column[2];
	hcolumn[5]=(column[3]-column[2])/2+column[2];
	hcolumn[6]=column[3];
	hcolumn[7]=(column[4]-column[3])/2+column[3];
	hcolumn[8]=column[4];

	hrow[0]=row[0];
	hrow[1]=(row[1]-row[0])/2;
	hrow[2]=row[1];
	hrow[3]=(row[2]-row[1])/2+row[1];
	hrow[4]=row[2];
	hrow[5]=(row[3]-row[2])/2+row[2];
	hrow[6]=row[3];
	hrow[7]=(row[4]-row[3])/2+row[3];
	hrow[8]=row[4];

	qcolumn[0]=hcolumn[0];
	qcolumn[1]=(hcolumn[1]-hcolumn[0])/2+hcolumn[0];
	qcolumn[2]=hcolumn[1];
	qcolumn[3]=(hcolumn[2]-hcolumn[1])/2+hcolumn[1];
	qcolumn[4]=hcolumn[2];
	qcolumn[5]=(hcolumn[3]-hcolumn[2])/2+hcolumn[2];
	qcolumn[6]=hcolumn[3];
	qcolumn[7]=(hcolumn[4]-hcolumn[3])/2+hcolumn[3];
	qcolumn[8]=hcolumn[4];
	qcolumn[9]=(hcolumn[5]-hcolumn[4])/2+hcolumn[4];
	qcolumn[10]=hcolumn[5];
	qcolumn[11]=(hcolumn[6]-hcolumn[5])/2+hcolumn[5];
	qcolumn[12]=hcolumn[6];
	qcolumn[13]=(hcolumn[7]-hcolumn[6])/2+hcolumn[6];
	qcolumn[14]=hcolumn[7];
	qcolumn[15]=(hcolumn[8]-hcolumn[7])/2+hcolumn[7];
	qcolumn[16]=hcolumn[8];

	qrow[0]=hrow[0];
	qrow[1]=(hrow[1]-hrow[0])/2+hrow[0];
	qrow[2]=hrow[1];
	qrow[3]=(hrow[2]-hrow[1])/2+hrow[1];
	qrow[4]=hrow[2];
	qrow[5]=(hrow[3]-hrow[2])/2+hrow[2];
	qrow[6]=hrow[3];
	qrow[7]=(hrow[4]-hrow[3])/2+hrow[3];
	qrow[8]=hrow[4];
	qrow[9]=(hrow[5]-hrow[4])/2+hrow[4];
	qrow[10]=hrow[5];
	qrow[11]=(hrow[6]-hrow[5])/2+hrow[5];
	qrow[12]=hrow[6];
	qrow[13]=(hrow[7]-hrow[6])/2+hrow[6];
	qrow[14]=hrow[7];
	qrow[15]=(hrow[8]-hrow[7])/2+hrow[7];
	qrow[16]=hrow[8];

	qrow[5]+=NIBLSCALE(6);
	qrow[6]+=NIBLSCALE(6);
	qrow[7]+=NIBLSCALE(6);
	qrow[8]+=NIBLSCALE(6)*2;
	qrow[9]+=NIBLSCALE(6)*2;
	qrow[10]+=NIBLSCALE(6)*2;
	qrow[11]+=NIBLSCALE(6)*3;
	qrow[12]+=NIBLSCALE(6)*3;
	qrow[13]+=NIBLSCALE(6)*3;

  } // doinit

#include "./LKMW3include2.cpp"

	SelectObject(hdc, LK8PanelBigFont);
#include "./LKMW3include1.cpp"

	int curtype; // 100404
	bool ontarget=false;
	FLARM_TRAFFIC *pTarget=NULL;
	if ( (MapSpaceMode != MSM_INFO_TRF) && (MapSpaceMode != MSM_INFO_TARGET) ) {
		curtype=CURTYPE;
	} else {
		if (MapSpaceMode == MSM_INFO_TRF)
			curtype=IM_TRF + IM_TOP;
		else
			curtype=IM_TARGET + IM_TOP;

		if (LKTargetIndex<0 || LKTargetIndex>=MAXTRAFFIC) {
			ontarget=false;
		} else {
			if (DrawInfo.FLARM_Traffic[LKTargetIndex].ID <=0) {
				ontarget=false;
			} else {
				ontarget=true;
				pTarget=&DrawInfo.FLARM_Traffic[LKTargetIndex];
			}
		}
	}

	if (ontarget) DoTarget(&DrawInfo, &DerivedDrawInfo);

	switch (LKevent) {
		case LKEVENT_NONE:
			break;
		case LKEVENT_ENTER:
			break;
		case LKEVENT_NEWRUN:
			break;
		case LKEVENT_PAGEUP:
			break;
		case LKEVENT_PAGEDOWN:
			break;
		default:
			break;
	}
	LKevent=LKEVENT_NONE; 

	COLORREF icolor; // 091229

	// R0 C0	= status
	SelectObject(hdc, LK8PanelMediumFont);
	switch(curtype) {
		case IM_THERMAL:
			_stprintf(Buffer,_T("%d.%d %s"),ModeIndex, curtype+1, gettext(TEXT("_@M905_"))); // Thermal
			break;
		case IM_CRUISE:
			_stprintf(Buffer,_T("%d.%d %s"),ModeIndex, curtype+1, gettext(TEXT("_@M906_"))); // Cruise
			break;
		case IM_TASK:
			_stprintf(Buffer,_T("%d.%d %s"),ModeIndex, curtype+1, gettext(TEXT("_@M907_"))); // Task
			break;
		case IM_AUX:
			_stprintf(Buffer,_T("%d.%d %s"),ModeIndex, curtype+1, gettext(TEXT("_@M908_"))); // Custom
			break;
		case IM_TRI:
#ifndef LKCOMPETITION
			_stprintf(Buffer,_T("%d.%d %s"), ModeIndex, curtype+1, gettext(TEXT("_@M909_"))); // Turn
#else
			_stprintf(Buffer,_T("%d.%d %s"), ModeIndex, curtype+1, gettext(TEXT("_@M1600_"))); // DISABLED
#endif
			break;
		case IM_HSI:
			wsprintf(Buffer,_T("%d.%d %s"), ModeIndex, curtype+1, gettext(TEXT("_@M1860_"))); // HSI
			break;
		case IM_CONTEST:
			_stprintf(Buffer,_T("%d.%d %s"), ModeIndex, curtype+1, gettext(TEXT("_@M957_"))); // Contest
			break;
		case IM_TRF+IM_TOP:
			_stprintf(Buffer,_T("%d.%d %s"), ModeIndex, IM_TRF+1, gettext(TEXT("_@M910_"))); // Target
			break;
		case IM_TARGET+IM_TOP:
			_stprintf(Buffer,_T("%d.%d %s"), ModeIndex, IM_TARGET+1, gettext(TEXT("_@M911_"))); // Sight
			break;
		default:
			_stprintf(Buffer,_T("error"));
			break;
	}
        LKWriteText(hdc, Buffer, qcolumn[0],qrow[0], 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false);

	// R0 C1
	icolor=RGB_WHITE;
	switch(curtype) {
		case IM_THERMAL:
		case IM_CRUISE:
		case IM_TASK:
		case IM_AUX:
			if ( ValidTaskPoint(ActiveWayPoint) != false ) {
				index = Task[ActiveWayPoint].Index;
				if ( index >=0 ) {
					_tcscpy(Buffer, WayPointList[index].Name);
				} else {
					_stprintf(Buffer,gettext(TEXT("_@M912_"))); // [no dest]
					icolor=RGB_AMBER;
				}
			} else {
				_stprintf(Buffer,gettext(TEXT("_@M912_"))); // [no dest]
				icolor=RGB_AMBER;
			}
			break;
		case IM_TRI:
#ifndef LKCOMPETITION
			_stprintf(Buffer,gettext(TEXT("_@M913_"))); // Experimental
#else
			_stprintf(Buffer,_T("---"));
#endif
			break;
		case IM_CONTEST:
		case IM_HSI: //for the HSI the title text is computed in his section down
			_stprintf(Buffer,gettext(TEXT("")));
			break;
		case IM_TRF+IM_TOP:
		case IM_TARGET+IM_TOP:
			if (ontarget) {
				switch (pTarget->Status ) {
					case LKT_GHOST:
						icolor=RGB_LIGHTYELLOW;
						break;
					case LKT_ZOMBIE:
						icolor=RGB_LIGHTRED;
						break;
					default:
						icolor=RGB_WHITE;
						break;
				}
				//TCHAR status[80];
				if (_tcslen(pTarget->Name) == 1) {
					_stprintf(Buffer,_T("%0x"),(unsigned)pTarget->ID);
				} else {
					_stprintf(Buffer,_T("%s"),pTarget->Name);
				}

			} else {
				_stprintf(Buffer,gettext(TEXT("_@M914_"))); // [no target]
				icolor=RGB_AMBER;
			}

			break;
		default:
			_stprintf(Buffer,_T("error"));
			icolor=RGB_AMBER;
			break;
	}
        LKWriteText(hdc, Buffer, qcolumn[8],qrow[1], 0, WTMODE_NORMAL, WTALIGN_CENTER, icolor, false);

	// R0 C2	= time of day
	if ( (curtype == (IM_TOP+IM_TRF)) || (curtype == (IM_TOP+IM_TARGET)) ) {
		if (ontarget) {
			TCHAR tpas[30];
			Units::TimeToTextDown(tpas,(int)(DrawInfo.Time - pTarget->Time_Fix));

			switch (pTarget->Status) {
				case LKT_REAL:
					_stprintf(Buffer,_T("LIVE"));
					break;
				case LKT_GHOST:
					_stprintf(Buffer,_T("ghost %s\""),tpas);
					break;
				case LKT_ZOMBIE:
					_stprintf(Buffer,_T("zombie %s\""),tpas);
					break;
				default:
					_stprintf(Buffer,_T("??? %s\""),tpas);
					break;
			}
        		LKWriteText(hdc, Buffer, qcolumn[16],qrow[0], 0, WTMODE_NORMAL, WTALIGN_RIGHT, icolor, false);
		} else {
			LKFormatValue(LK_TIME_LOCALSEC, false, BufferValue, BufferUnit, BufferTitle); // 091219
        		LKWriteText(hdc, BufferValue, qcolumn[16],qrow[0], 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false);
		}
		if ( curtype == (IM_TOP+IM_TARGET) ) goto label_Target;
	} else {
		LKFormatValue(LK_TIME_LOCALSEC, false, BufferValue, BufferUnit, BufferTitle); // 091219
        	LKWriteText(hdc, BufferValue, qcolumn[16],qrow[0], 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false);
	}

	if (curtype == IM_TRI) goto label_TRI;
	if (curtype == IM_HSI) goto label_HSI;

	VDrawLine(hdc,rc, qcolumn[0],qrow[2],qcolumn[16],qrow[2],RGB_DARKGREEN);
	VDrawLine(hdc,rc, qcolumn[0],qrow[8],qcolumn[16],qrow[8],RGB_DARKGREEN);

	// R1 C1
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_NEXT_DIST, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_NEXT_DIST, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_AUX:
			index=GetInfoboxType(1);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_CLASSIC_DIST, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_DIST, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4], &qrow[3],&qrow[4],&qrow[2]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4], &qrow[3],&qrow[4],&qrow[2]);
			break;
	}

	// R1 C2
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_BRG, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8],&qcolumn[8], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_BRGDIFF, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9],&qcolumn[8], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_FAI_DIST, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8],&qcolumn[8], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_AUX:
			index=GetInfoboxType(2);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8],&qcolumn[8], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_TO, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9],&qcolumn[8], &qrow[3],&qrow[4],&qrow[2]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9],&qcolumn[8], &qrow[3],&qrow[4],&qrow[2]);
			break;
	}


	// R1 C3
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_NEXT_ALTDIFF, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_NEXT_GR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_LEAGUE_DIST, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_AUX:
			index=GetInfoboxType(3);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12], &qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_GR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12], &qrow[3],&qrow[4],&qrow[2]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12], &qrow[3],&qrow[4],&qrow[2]);
			break;
	}

	// R1 C4
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_NEXT_GR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16],&qcolumn[16], 
											&qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_LD_AVR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16],&qcolumn[16], 
											&qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_3TPS_DIST, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16],&qcolumn[16], 
											&qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_AUX:
			index=GetInfoboxType(4);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16],&qcolumn[16], 
											&qrow[3],&qrow[4],&qrow[2]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_ALTARRIV, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16],&qcolumn[16], 
											&qrow[3],&qrow[4],&qrow[2]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16],&qcolumn[16], 
											&qrow[3],&qrow[4],&qrow[2]);
			break;
	}

	// R2  C1
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_HNAV, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_NEXT_ALTDIFF, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_CLASSIC_PREDICTED_DIST, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_AUX:
			index=GetInfoboxType(5);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_ALTDIFF, false, BufferValue, BufferUnit, BufferTitle);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4],&qcolumn[4], &qrow[6],&qrow[7],&qrow[5]);

	// R2  C2
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_GNDSPEED, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8], &qrow[6],&qrow[7],&qrow[5]);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_BRG, true , BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[8], &qrow[6],&qrow[7],&qrow[5]);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_FAI_PREDICTED_DIST, true , BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8], &qrow[6],&qrow[7],&qrow[5]);
			break;
		case IM_AUX:
			index=GetInfoboxType(6);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8], &qrow[6],&qrow[7],&qrow[5]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_BEARING, true , BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[8], &qrow[6],&qrow[7],&qrow[5]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[8], &qrow[6],&qrow[7],&qrow[5]);
			break;
	}

	// R2  C3
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_VARIO, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_LD_CRUISE, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CONTEST:
			_tcscpy(BufferValue,_T("")); 
            _tcscpy(BufferTitle,_T(""));
			break;
		case IM_AUX:
			index=GetInfoboxType(7);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_EMPTY, true , BufferValue, BufferUnit, BufferTitle);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12],&qrow[6],&qrow[7],&qrow[5]);

	// R2  C4
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_FL, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_LD_INST, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_3TPS_PREDICTED_DIST, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
		case IM_AUX:
			index=GetInfoboxType(8);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_EMPTY, false, BufferValue, BufferUnit, BufferTitle);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[6],&qrow[7],&qrow[5]);

	// R3  C1
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_TC_GAIN, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_HNAV, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_FIN_ALTDIFF, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CONTEST:
			//showunit=LKFormatValue(LK_OLC_PLUS_SCORE, false, BufferValue, BufferUnit, BufferTitle);
			showunit=LKFormatValue(LK_OLC_CLASSIC_SPEED, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_AUX:
			index=GetInfoboxType(9);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_ALT, false, BufferValue, BufferUnit, BufferTitle);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[9],&qrow[10],&qrow[8]);

	// R3  C2
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_TC_30S, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_TRACK, true, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_FIN_DIST, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
		case IM_CONTEST:
			//showunit=LKFormatValue(LK_OLC_PLUS_PREDICTED_SCORE, false, BufferValue, BufferUnit, BufferTitle);
			showunit=LKFormatValue(LK_OLC_FAI_SPEED, false, BufferValue, BufferUnit, BufferTitle); 
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
		case IM_AUX:
			index=GetInfoboxType(10);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_SPEED, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[8],&qrow[9],&qrow[10],&qrow[8]);
			break;
	}

	// R3  C3
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_TC_AVG, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_GNDSPEED, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_TASK_DISTCOV, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CONTEST:
			//showunit=LKFormatValue(LK_OLC_LEAGUE_SCORE, false, BufferValue, BufferUnit, BufferTitle);
			showunit=LKFormatValue(LK_OLC_LEAGUE_SPEED, true, BufferValue, BufferUnit, BufferTitle); 
			break;
		case IM_AUX:
			index=GetInfoboxType(11);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_VARIO, false, BufferValue, BufferUnit, BufferTitle);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12],&qrow[9],&qrow[10],&qrow[8]);


	// R3  C4
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_TC_ALL, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_FL, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_FIN_GR, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_3TPS_SPEED, true, BufferValue, BufferUnit, BufferTitle); 
			_tcscpy(BufferUnit,_T(""));
			break;
		case IM_AUX:
			index=GetInfoboxType(12);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_AVGVARIO, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[9],&qrow[10],&qrow[8]);


	// R4  C1
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_WIND, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[5], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_WIND, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[5], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_FIN_ALTDIFF0, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_CONTEST:
			showunit=LKFormatValue(LK_OLC_PLUS_SCORE, false, BufferValue, BufferUnit, BufferTitle);
			//showunit=LKFormatValue(LK_OLC_CLASSIC_SPEED, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_AUX:
			index=GetInfoboxType(13);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_TRF+IM_TOP:
			LKFormatValue(LK_EMPTY, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
			break;
	}

	// R4  C2
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_EMPTY, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[9],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_TL_AVG, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[9],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_LKFIN_ETE, false, BufferValue, BufferUnit, BufferTitle); 
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[9],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_CONTEST:
			//showunit=LKFormatValue(LK_OLC_FAI_SPEED, false, BufferValue, BufferUnit, BufferTitle); 
			showunit=LKFormatValue(LK_OLC_PLUS_PREDICTED_SCORE, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_AUX:
			index=GetInfoboxType(14);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_TARGET_EIAS, false, BufferValue, BufferUnit, BufferTitle); 
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[8], &qcolumn[8],&qrow[12],&qrow[13],&qrow[11]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[9], &qcolumn[9],&qrow[12],&qrow[13],&qrow[11]);
			break;
	}

	// R4  C3
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_EMPTY, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[13], &qcolumn[13],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_CRUISE:
			showunit=LKFormatValue(LK_TC_ALL, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[13], &qcolumn[13],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_TASK:
			showunit=LKFormatValue(LK_SPEEDTASK_ACH, true, BufferValue, BufferUnit, BufferTitle); 
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[13], &qcolumn[13],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_CONTEST:
			//showunit=LKFormatValue(LK_OLC_LEAGUE_SPEED, true, BufferValue, BufferUnit, BufferTitle); 
			showunit=LKFormatValue(LK_OLC_LEAGUE_SCORE, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_AUX:
			index=GetInfoboxType(15);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[12], &qcolumn[12],&qrow[12],&qrow[13],&qrow[11]);
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_EMPTY, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[13], &qcolumn[13],&qrow[12],&qrow[13],&qrow[11]);
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[13], &qcolumn[13],&qrow[12],&qrow[13],&qrow[11]);
			break;
	}

	// R4  C4
	showunit=false;
	switch(curtype) {
		case IM_THERMAL:
			showunit=LKFormatValue(LK_EMPTY, false, BufferValue, BufferUnit, BufferTitle);
			break;
		case IM_CRUISE:
		case IM_TASK:
			showunit=LKFormatValue(LK_MC, true, BufferValue, BufferUnit, BufferTitle); 
			break;
		case IM_CONTEST:
			_tcscpy(BufferValue,_T("")); 
            _tcscpy(BufferTitle,_T(""));
			//showunit=LKFormatValue(LK_OLC_3TPS_SPEED, true, BufferValue, BufferUnit, BufferTitle); 
			break;
		case IM_AUX:
			index=GetInfoboxType(16);
			showunit=LKFormatValue(index, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
		case IM_TRF+IM_TOP:
			showunit=LKFormatValue(LK_EMPTY, true, BufferValue, BufferUnit, BufferTitle); 
			break;
		default:
			LKFormatValue(LK_ERROR, false, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			break;
	}
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[12],&qrow[13],&qrow[11]);
	goto label_End;

	// This is the TRI page
	//
	// ATTENTION PLEASE
	// Some values are using direct access to CALCULATED_INFO for fast responses.
	// Other values are using the copy of struct made 1 second later
	//
label_TRI:
#ifndef LKCOMPETITION
	VDrawLine(hdc,rc, qcolumn[0],qrow[2],qcolumn[16],qrow[2],RGB_DARKGREEN);
	DrawTRI(hdc, rc);
	showunit=true; // 091219
	if (ScreenLandscape) {
		// right
		LKFormatValue(LK_TRACK, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[14], &qcolumn[14],&qrow[3],&qrow[4],&qrow[2]);
		LKFormatValue(LK_GNDSPEED, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[14], &qcolumn[14],&qrow[6],&qrow[7],&qrow[5]);
		LKFormatValue(LK_HNAV, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[15], &qcolumn[15],&qrow[9],&qrow[10],&qrow[8]);
		LKFormatValue(LK_VARIO, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[14], &qcolumn[14],&qrow[12],&qrow[13],&qrow[11]);

		// left
		LKFormatValue(LK_IAS, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[6],&qrow[7],&qrow[5]);
		LKFormatValue(LK_BANK_ANGLE, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[3],&qrow[4],&qrow[2]);
		LKFormatValue(LK_GLOAD, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[9],&qrow[10],&qrow[8]);
		LKFormatValue(LK_ODOMETER, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
	} else {
		// right
		LKFormatValue(LK_TRACK, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[14], &qcolumn[14],&qrow[3],&qrow[4],&qrow[2]);
		LKFormatValue(LK_GNDSPEED, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[6],&qrow[7],&qrow[5]);
		LKFormatValue(LK_HNAV, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[9],&qrow[10],&qrow[8]);
		LKFormatValue(LK_VARIO, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[12],&qrow[13],&qrow[11]);

		// left
		LKFormatValue(LK_IAS, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[6],&qrow[7],&qrow[5]);
		LKFormatValue(LK_BANK_ANGLE, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[3],&qrow[4],&qrow[2]);
		LKFormatValue(LK_GLOAD, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[9],&qrow[10],&qrow[8]);
		LKFormatValue(LK_ODOMETER, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
	}
#if 0
	_stprintf(BufferValue,_T("%0.1f"),CALCULATED_INFO.TurnRate);
	_stprintf(BufferTitle,_T("Rate"));
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[9],&qrow[10],&qrow[8]);

	LKFormatValue(LK_GLOAD, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
#endif
	wsprintf(BufferTitle, gettext(TEXT("_@M915_"))); // NOT FOR IFR USAGE
	SelectObject(hdc, LK8PanelSmallFont);
	LKWriteText(hdc, BufferTitle, qcolumn[8],qrow[12], 0, WTMODE_OUTLINED, WTALIGN_CENTER, RGB_ORANGE, false);
#endif // not in LKCOMPETITION 
	goto label_End; // End of TRI

	// This is the HSI page
label_HSI:
	VDrawLine(hdc,rc, qcolumn[0],qrow[2],qcolumn[16],qrow[2],RGB_DARKGREEN);
	static bool showQFU=false;
	static bool showVFRlanding=false;
	HSIreturnStruct HSI;
	HSI=DrawHSI(hdc,rc);
	if(HSI.landing) {
		showVFRlanding=!showVFRlanding; //make it blinking
		if(HSI.usingQFU) showQFU=!showVFRlanding;
		else showQFU=false;
	} else {
		showVFRlanding=false;
		if(HSI.usingQFU) showQFU=!showQFU; //make it blinking
		else showQFU=false;
	}
	if(showVFRlanding || showQFU) { //show QFU or "VFR landing"
		if(showVFRlanding) {
			wsprintf(Buffer,TEXT("VFR %s"),gettext(TEXT("_@M931_"))); //TODO: toupper()
			icolor=INVERTCOLORS?RGB_YELLOW:RGB_DARKYELLOW;
		}
		if(showQFU) {
			#ifndef __MINGW32__
			wsprintf(Buffer, TEXT("QFU: %d\xB0"),WayPointList[Task[ActiveWayPoint].Index].RunwayDir);
			#else
			wsprintf(Buffer, TEXT("QFU: %d°"),WayPointList[Task[ActiveWayPoint].Index].RunwayDir);
			#endif
			icolor=RGB_GREEN;
		}
	} else { //show next waypoint name
		icolor=RGB_WHITE;
		if(ValidTaskPoint(ActiveWayPoint)) {
			if(Task[ActiveWayPoint].Index >=0) _tcscpy(Buffer, WayPointList[Task[ActiveWayPoint].Index].Name);
			else {
				wsprintf(Buffer,gettext(TEXT("_@M912_"))); // [no dest]
				icolor=RGB_AMBER;
			}
		} else {
			wsprintf(Buffer,gettext(TEXT("_@M912_"))); // [no dest]
			icolor=RGB_AMBER;
		}
	}
	SelectObject(hdc, LK8PanelMediumFont);
	LKWriteText(hdc, Buffer, qcolumn[8],qrow[1], 0, WTMODE_NORMAL, WTALIGN_CENTER, icolor, false);
	showunit=true;
	if (ScreenLandscape) {
		LKFormatValue(LK_NEXT_ETE, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[3],&qrow[4],&qrow[2]);
		LKFormatValue(LK_NEXT_DIST, true, BufferValue, BufferUnit, BufferTitle);
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[7],&qrow[8],&qrow[6]);
		LKFormatValue(LK_NEXT_ETA, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
		if(!HSI.approach) { //if not landing print also dist, ETE and ETA respect task end
			LKFormatValue(LK_FIN_ETE, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[3],&qrow[4],&qrow[2]);
			LKFormatValue(LK_FIN_DIST, true, BufferValue, BufferUnit, BufferTitle);
			if(ScreenSize==ss800x480 || ScreenSize==ss480x272)
				WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[15], &qcolumn[15],&qrow[7],&qrow[8],&qrow[6]);
			else {
				_tcscpy(BufferUnit,_T(""));
				WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[7],&qrow[8],&qrow[6]);
			}
			LKFormatValue(LK_FIN_ETA, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[12],&qrow[13],&qrow[11]);
		} else { //show other interesting things for landing
			int col=16;
			bool unitInvisible=true;
			if(ScreenSize==ss800x480 || ScreenSize==ss480x272) {
				col=15;
				unitInvisible=false;
			}
			LKFormatValue(LK_IAS, true, BufferValue, BufferUnit, BufferTitle);
			if(unitInvisible) _tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[col], &qcolumn[col],&qrow[3],&qrow[4],&qrow[2]);
			LKFormatValue(LK_HAGL, true, BufferValue, BufferUnit, BufferTitle);
			if(unitInvisible) _tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[col], &qcolumn[col],&qrow[12],&qrow[13],&qrow[11]);
		}
	} else {
		LKFormatValue(LK_NEXT_ETE, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[3],&qrow[4],&qrow[2]);
		LKFormatValue(LK_NEXT_DIST, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[6],&qrow[7],&qrow[5]);
		LKFormatValue(LK_NEXT_ETA, true, BufferValue, BufferUnit, BufferTitle);
		_tcscpy(BufferUnit,_T(""));
		WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[4], &qcolumn[4],&qrow[12],&qrow[13],&qrow[11]);
		if(!HSI.approach) { //if not landing print also dist, ETE and ETA respect task end
			LKFormatValue(LK_FIN_ETE, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[3],&qrow[4],&qrow[2]);
			LKFormatValue(LK_FIN_DIST, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[6],&qrow[7],&qrow[5]);
			LKFormatValue(LK_FIN_ETA, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[12],&qrow[13],&qrow[11]);
		} else {
			LKFormatValue(LK_IAS, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[3],&qrow[4],&qrow[2]);
			LKFormatValue(LK_HAGL, true, BufferValue, BufferUnit, BufferTitle);
			_tcscpy(BufferUnit,_T(""));
			WriteInfo(hdc, &showunit, BufferValue, BufferUnit, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[12],&qrow[13],&qrow[11]);
		}
	}
	goto label_End; // End of HSI

	// Traffic Target page
	
label_Target:
	VDrawLine(hdc,rc, qcolumn[0],qrow[2],qcolumn[16],qrow[2],RGB_DARKGREEN);
	// pass the sight rectangle to use on the screen. Warning: DrawTarget will cache these values
	// and will not use them after the first run time anymore...
	DrawTarget(hdc, rc, qrow[3],qrow[15],qcolumn[3],qcolumn[13]);

	showunit=false; // 091219

	// left
	
	showunit=LKFormatValue(LK_TARGET_DIST, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[3],&qrow[4],&qrow[2]);

	showunit=LKFormatValue(LK_TARGET_EIAS, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[6],&qrow[7],&qrow[5]);

	showunit=LKFormatValue(LK_TARGET_AVGVARIO, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[9],&qrow[10],&qrow[8]);

	showunit=LKFormatValue(LK_TARGET_GR, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[3], &qcolumn[3],&qrow[12],&qrow[13],&qrow[11]);

	// right
	showunit=LKFormatValue(LK_TARGET_ALTDIFF, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[3],&qrow[4],&qrow[2]);

	showunit=LKFormatValue(LK_EMPTY, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[6],&qrow[7],&qrow[5]);

	showunit=LKFormatValue(LK_EMPTY, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[9],&qrow[10],&qrow[8]);

	showunit=LKFormatValue(LK_TARGET_ALTARRIV, true, BufferValue, BufferUnit, BufferTitle);
	WriteInfo(hdc, &showunit, BufferValue, Empty, BufferTitle, &qcolumn[16], &qcolumn[16],&qrow[12],&qrow[13],&qrow[11]);


label_End:
  // restore font and return
  SelectObject(hdc, oldfont); 

}