Login Page - Create Account

Support Board


Date/Time: Mon, 25 Nov 2024 09:44:53 +0000



[Programming Help] - GDI Flickering

View Count: 273

[2024-03-15 20:24:51]
TPH_Main - Posts: 13
I have tried the code below with Open GL enabled and not enabled.
Basically if I have two charts open
1. apply this study.
2. change x/y inputs of the study on one chart
3. Flickering happens or the indicator is being redrawn in both the old input settings and the new input settings.


#pragma once

struct LabelSettings
{
int xPosition;
int yPosition;
int alignment;
int fontSize;
COLORREF fontColor;
COLORREF bgColor;
COLORREF invalidBgColor;
};

LabelSettings LabelSettings;

// FUNCTION: Draw Info
void DrawLabel(HWND WindowHandle,
HDC DeviceContext,
SCStudyInterfaceRef sc)
{
// Set drawing font
n_ACSIL::s_GraphicsFont GraphicsFont;
GraphicsFont.m_FaceName = sc.ChartTextFont();
GraphicsFont.m_Height = LabelSettings.fontSize;
GraphicsFont.m_Weight = FW_BOLD;
sc.Graphics.SetTextFont(GraphicsFont);

// Set colors
n_ACSIL::s_GraphicsColor fontColor;
fontColor.SetColorValue(LabelSettings.fontColor);
sc.Graphics.SetTextColor(fontColor);

n_ACSIL::s_GraphicsColor GraphicsColor;
GraphicsColor.SetColorValue(LabelSettings.bgColor);
sc.Graphics.SetBackgroundColor(GraphicsColor);

// Set position
int width = sc.ChartRegion1RightCoordinate - sc.ChartRegion1LeftCoordinate;
int height = sc.ChartRegion1BottomCoordinate - sc.ChartRegion1TopCoordinate;

int xPosition = width * LabelSettings.xPosition / 100.00;
int yPosition = height * LabelSettings.yPosition / 100.00;
switch (LabelSettings.alignment)
{
case 0:
sc.Graphics.SetTextAlign(TA_LEFT);
break;
case 1:
sc.Graphics.SetTextAlign(TA_CENTER);
break;
case 2:
sc.Graphics.SetTextAlign(TA_RIGHT);
break;
default:
sc.Graphics.SetTextAlign(TA_CENTER);
break;
}

// Draw
sc.Graphics.DrawTextAt("testing 123", xPosition, yPosition);
}

SCSFExport scsf_Test_GDILabels(SCStudyInterfaceRef sc)
{

int inputNum = -1;
SCInputRef Input_FontxPOS = sc.Input[++inputNum];
SCInputRef Input_FontyPOS = sc.Input[++inputNum];
SCInputRef Input_FontAlignment = sc.Input[++inputNum];

SCInputRef Input_FontSize = sc.Input[++inputNum];
SCInputRef Input_FontColorCSS = sc.Input[++inputNum];
SCInputRef Input_BgColorCSS = sc.Input[++inputNum];
SCInputRef Input_InvalidBgColorCSS = sc.Input[++inputNum];

if (sc.SetDefaults)
{
sc.GraphName = "Test";
sc.GraphRegion = 0;
sc.AutoLoop = 0;
// sc.UpdateAlways = 1;

sc.HideDLLAndFunctionNames = 1;
sc.HideStudy = 0;
sc.IncludeInStudySummary = 0;
sc.IncludeInSpreadsheet = 0;
sc.AlertConditionEnabled = 0;
sc.DisplayStudyInputValues = 0;
sc.DisplayStudyName = 0;
sc.GlobalDisplayStudySubgraphsNameAndValue = 0;
sc.ProtectStudy = 1;
sc.CalculationPrecedence = STD_PREC_LEVEL;

Input_FontxPOS.Name = "Label x Position";
Input_FontxPOS.SetInt(100);
Input_FontxPOS.SetIntLimits(1, 100);

Input_FontyPOS.Name = "Label y Position";
Input_FontyPOS.SetInt(3);
Input_FontyPOS.SetIntLimits(1, 100);

Input_FontAlignment.Name = "Label Alignment";
Input_FontAlignment.SetCustomInputStrings("Left;Center;Right");
Input_FontAlignment.SetCustomInputIndex(2);

Input_FontSize.Name = "Font Size";
Input_FontSize.SetInt(10);
Input_FontSize.SetIntLimits(6, 36);

Input_FontColorCSS.Name = "Font Color";
Input_FontColorCSS.SetColor(255, 255, 255);

Input_BgColorCSS.Name = "Background Color";
Input_BgColorCSS.SetColor(90, 100, 113);

Input_InvalidBgColorCSS.Name = "Invalid Background Color";
Input_InvalidBgColorCSS.SetColor(255, 0, 255);
}

// Set Colors
LabelSettings.xPosition = Input_FontxPOS.GetInt();
LabelSettings.yPosition = Input_FontyPOS.GetInt();
LabelSettings.alignment = Input_FontAlignment.GetIndex();
LabelSettings.fontSize = Input_FontSize.GetInt();
LabelSettings.fontColor = Input_FontColorCSS.GetColor();
LabelSettings.bgColor = Input_BgColorCSS.GetColor();
LabelSettings.invalidBgColor = Input_InvalidBgColorCSS.GetColor();

// Hook drawing function
sc.p_GDIFunction = DrawLabel;
}
[2024-03-15 21:08:10]
TPH_Main - Posts: 13
Charts do not need to be in the same chartbook either.
[2024-03-15 21:17:01]
User431178 - Posts: 541
Your Labelsettings structure is a global variable shared by all copies of the study.
Unless the settings are the same in both studies, it will flicker/move each time the differing settings are changed.
You need separate for each copy of the study, or just read the inputs directly in the drawing function.
[2024-03-15 21:47:48]
TPH_Main - Posts: 13
// #pragma once

void DrawToChart(HWND WindowHandle, HDC DeviceContext, SCStudyInterfaceRef sc);

SCSFExport scsf_Test_GDILabels(SCStudyInterfaceRef sc)
{

int inputNum = -1;
SCInputRef Input_FontxPOS = sc.Input[++inputNum];
SCInputRef Input_FontyPOS = sc.Input[++inputNum];
SCInputRef Input_FontAlignment = sc.Input[++inputNum];

SCInputRef Input_FontSize = sc.Input[++inputNum];
SCInputRef Input_FontColorCSS = sc.Input[++inputNum];
SCInputRef Input_BgColorCSS = sc.Input[++inputNum];
SCInputRef Input_InvalidBgColorCSS = sc.Input[++inputNum];

if (sc.SetDefaults)
{
sc.GraphName = "Test";
sc.GraphRegion = 0;
// sc.AutoLoop = 1;
// sc.UpdateAlways = 1;

sc.HideDLLAndFunctionNames = 1;
sc.HideStudy = 0;
sc.IncludeInStudySummary = 0;
sc.IncludeInSpreadsheet = 0;
sc.AlertConditionEnabled = 0;
sc.DisplayStudyInputValues = 0;
sc.DisplayStudyName = 0;
sc.GlobalDisplayStudySubgraphsNameAndValue = 0;
sc.ProtectStudy = 1;
sc.CalculationPrecedence = STD_PREC_LEVEL;

Input_FontxPOS.Name = "Label x Position";
Input_FontxPOS.SetInt(100);
Input_FontxPOS.SetIntLimits(1, 100);

Input_FontyPOS.Name = "Label y Position";
Input_FontyPOS.SetInt(3);
Input_FontyPOS.SetIntLimits(1, 100);

Input_FontAlignment.Name = "Label Alignment";
Input_FontAlignment.SetCustomInputStrings("Left;Center;Right");
Input_FontAlignment.SetCustomInputIndex(2);

Input_FontSize.Name = "Font Size";
Input_FontSize.SetInt(10);
Input_FontSize.SetIntLimits(6, 36);

Input_FontColorCSS.Name = "Font Color";
Input_FontColorCSS.SetColor(255, 255, 255);

Input_BgColorCSS.Name = "Background Color";
Input_BgColorCSS.SetColor(90, 100, 113);

Input_InvalidBgColorCSS.Name = "Invalid Background Color";
Input_InvalidBgColorCSS.SetColor(255, 0, 255);
}

// Hook drawing function
sc.p_GDIFunction = DrawToChart;
}

void DrawToChart(HWND WindowHandle, HDC DeviceContext, SCStudyInterfaceRef sc)
{
// Inputs
int inputNum = -1;
SCInputRef Input_FontxPOS = sc.Input[++inputNum];
SCInputRef Input_FontyPOS = sc.Input[++inputNum];
SCInputRef Input_FontAlignment = sc.Input[++inputNum];

SCInputRef Input_FontSize = sc.Input[++inputNum];
SCInputRef Input_FontColorCSS = sc.Input[++inputNum];
SCInputRef Input_BgColorCSS = sc.Input[++inputNum];
SCInputRef Input_InvalidBgColorCSS = sc.Input[++inputNum];

// Set drawing font
n_ACSIL::s_GraphicsFont GraphicsFont;
GraphicsFont.m_FaceName = sc.ChartTextFont();
GraphicsFont.m_Height = Input_FontSize.GetInt();
GraphicsFont.m_Weight = FW_BOLD;
sc.Graphics.SetTextFont(GraphicsFont);

// Set colors
n_ACSIL::s_GraphicsColor fontColor;
fontColor.SetColorValue(Input_FontColorCSS.GetColor());
sc.Graphics.SetTextColor(fontColor);

n_ACSIL::s_GraphicsColor GraphicsColor;
GraphicsColor.SetColorValue(Input_BgColorCSS.GetColor());
sc.Graphics.SetBackgroundColor(GraphicsColor);

// Set position
int width = sc.ChartRegion1RightCoordinate - sc.ChartRegion1LeftCoordinate;
int height = sc.ChartRegion1BottomCoordinate - sc.ChartRegion1TopCoordinate;

int xPosition = width * Input_FontxPOS.GetInt() / 100.00;
int yPosition = height * Input_FontyPOS.GetInt() / 100.00;
switch (Input_FontAlignment.GetIndex())
{
case 0:
sc.Graphics.SetTextAlign(TA_LEFT);
break;
case 1:
sc.Graphics.SetTextAlign(TA_CENTER);
break;
case 2:
sc.Graphics.SetTextAlign(TA_RIGHT);
break;
default:
sc.Graphics.SetTextAlign(TA_CENTER);
break;
}

// Draw
sc.Graphics.DrawTextAt("testing 123", xPosition, yPosition);

// Debug
// SCString typeString;
// typeString.Format("TEST:%d",
// Input_FontxPOS.GetInt());
// sc.AddMessageToLog(typeString, 0);
}



So this is working correctly it just seems strange to define inputs twice...idk maybe Sierra Chart Engineers could explain why to help clarify.


Thank you.
[2024-03-15 22:31:34]
User431178 - Posts: 541
The scope of the inputs, and all other variable, is limited to the function in which they are declared.
The study and drawing are separate functions.
Date Time Of Last Edit: 2024-03-16 09:09:17
[2024-03-16 00:12:34]
TPH_Main - Posts: 13
For anybody else who stumbles upon this, to not define the inputs twice you can still use the struct just use a persistent int for it. Again don't know if this is the best solution, but it works for me.

Inside SCSFExport Function
// Create persistent storage
s_Data *Data = (s_Data *)sc.GetPersistentPointer(0);
if (Data == NULL)
{
Data = new s_Data();
sc.SetPersistentPointer(0, Data);
}

// Example Setting data
Data->xPOS = Input_FontxPOS.GetInt();
Data->yPOS = Input_FontyPOS.GetInt();
Data->alignment = Input_FontAlignment.GetInt();
Data->fontSize = Input_FontSize.GetInt();
Data->fontColor = Input_FontColorCSS.GetColor();
Data->bgColor = Input_BgColorCSS.GetColor();
Data->invalidBgColor = Input_InvalidBgColorCSS.GetColor();


Drawing Function
void DrawTradeCopierLabels(HWND WindowHandle,
HDC DeviceContext,
SCStudyInterfaceRef sc)
{

// Fetch Data from main function
s_Data *Data = (s_Data *)sc.GetPersistentPointer(0);
if (Data == NULL)
return;


// Using data
int width = sc.ChartRegion1RightCoordinate - sc.ChartRegion1LeftCoordinate;
int height = sc.ChartRegion1BottomCoordinate - sc.ChartRegion1TopCoordinate;

int xPosition = static_cast<int>(width * CopyTradingData->xPOS / 100.00);
int yPosition = static_cast<int>(height * CopyTradingData->yPOS / 100.00);
}

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account