Displaying a negative time in Delphi - delphi

I am developing a timer in Delphi 2009. I am currently using the following to format my timer display:
Caption := Format('%.2d', [Hours]) + ':' +
Format('%.2d', [Minutes]) + ':' +
Format('%.2d', [Seconds]);
and this as expected displays the time as:
00:04:35
However, when I go into negative time it is understandably displaying it as:
00:-04:-35
I need the time to display as:
-00:04:35
Any Ideas?

Prefix:='';
if (Hours<0) or (Minutes<0) or (Seconds<0) then
Prefix:='-';
Caption := Prefix+Format('%.2d', [Abs(Hours)]) + ':' +
Format('%.2d', [Abs(Minutes)]) + ':' +
Format('%.2d', [Abs(Seconds)]);
Bye.

Well, you're formatting each number separately, therefore its no surprise you get negative sign on all of them. Try this:
Caption := Format('%.2d', [Abs(Hours)]) + ':' +
Format('%.2d', [Abs(Minutes)]) + ':' +
Format('%.2d', [Abs(Seconds)]);
if (Hours < 0) or (Minutes < 0) or (Seconds < 0) then begin
Caption := '-' + Caption;
end;

Related

Why does TFormatSettings use incorrect ShortTimeFormat?

After several hours of investigations and researching the problem, I've found that TFormatSettings returns an incorrect ShortTimeFormat.
To show in TDateTimePicker a short time format with support for 24-hours, I need to use: TDateTimePicker.Format :='H:mm', and this is a default setting for my profile in Windows 10 for a short time.
But TFormatSettings.ShortTimeFormat return me a value of 'h:mm'.
To get the correct value, I should use:
GetLocaleStr(LOCALE_USER_DEFAULT, LOCALE_SSHORTTIME, '');
And this returns a 'H:mm' value.
This is the source of TFormatSettings from SysUtils.pas:
TimePrefix := '';
TimePostfix := '';
if StrToIntDef(GetLocaleStr(Locale, LOCALE_ITLZERO, '0'), 0) = 0 then
HourFormat := 'h'
else
HourFormat := 'hh';
if StrToIntDef(GetLocaleStr(Locale, LOCALE_ITIME, '0'), 0) = 0 then
if StrToIntDef(GetLocaleStr(Locale, LOCALE_ITIMEMARKPOSN, '0'), 0) = 0 then
TimePostfix := ' AMPM'
else
TimePrefix := 'AMPM ';
Result.ShortTimeFormat := TimePrefix + HourFormat + ':mm' + TimePostfix;
Result.LongTimeFormat := TimePrefix + HourFormat + ':mm:ss' + TimePostfix;
As we can see, that always use 'h' or 'hh', no way to get 'H' or 'HH'.
My question is: Why?

Check if number of OrdersHistoryTotal in Metatrader 4 trade history changed

I would like to fire a function as soon as a trade was closed (= the OrdersHistoryTotal increased by at least 1).
Is there any handler in MQL4 for such scenarios?
In my particular setup I have the following function pushSocket which should only push data in case the OrdersHistoryTotal changed.
int i,hstTotal=OrdersHistoryTotal();
string historical_trades = "";
for(i=0;i<hstTotal;i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) continue;
historical_trades = historical_trades +
"historical_trades|" +
version + "|" +
DID + "|" +
AccountNumber() + "|" +
IntegerToString(OrderTicket()) + "," +
TimeToString(OrderOpenTime(), TIME_DATE|TIME_SECONDS) + "," +
TimeToString(OrderCloseTime(), TIME_DATE|TIME_SECONDS) + "," +
IntegerToString(OrderType()) + "," +
DoubleToString(OrderLots(),2) + "," +
OrderSymbol() + "," +
DoubleToString(OrderOpenPrice(),5) + "," +
DoubleToString(OrderClosePrice(),5) + "," +
DoubleToString(OrderStopLoss(),5) + "," +
DoubleToString(OrderTakeProfit(),5) + "," +
DoubleToString(OrderCommission(),2) + "," +
DoubleToString(OrderSwap(),2) + "," +
DoubleToString(OrderProfit(),2) + "," +
"<" + OrderComment() + ">|";
}
pushSocket.send(StringFormat("%s", historical_trades, true));
I tried to insert a counter to compare it but the counter is deleted every time on memory clean-up.. The above function is nested in a onTick function which executes every second.
There is a function OnTradeAction() in MQL5 that is called every time some trading action is done. But unfortunately this function is not available in MQL4. On the other hand, you can implement a function inside OnTick() that will check that HistoryTraderTotal() increased compared to the previously saved value, and do all the steps you like in that case. A bit more work but almost the same.
OnTimer(){
Mt4OnTradeAction();
otherLogic();
}
Mt4OnTradeAction(){
static int historyTradesTotal=0;
if(HistoryTradesTotal()==historyTradesTotal) return;
historyTradesTotal = HistoryTradesTotal();
processingTrade();
}

SQL Server CE - IMAGE column

I know that IMAGE datatype is deprecated since a while, but for my project I don't have the choice.
The question is: can I have several IMAGE columns in a table in SQL Server CE?
Because when I make an insert (ADO in Delphi) with more than 1 IMAGE column, my program hangs when I call ExecSQL().
With just one IMAGE column, it works:
HSLmySQL.ADOQuery1.SQL.Clear();
HSLmySQL.ADOQuery1.SQL.Add( 'INSERT INTO ' + CONFIG_Table_Name + ' SET ' +
CONFIG_Table[ aCONFIG_PARAM ] + '=' + ':param_blob'; + ' ;' );
HSLmySQL.ADOQuery1.Parameters.ParamByName('param_blob').LoadFromStream( Mstream1, ftBlob );
HSLmySQL.ADOQuery1.ExecSQL();
But with more than one IMAGE column:
HSLmySQL.ADOQuery1.SQL.Clear();
HSLmySQL.ADOQuery1.SQL.Add( 'INSERT INTO ' + CONFIG_Table_Name + ' SET ' +
CONFIG_Table[ aCONFIG_PARAM ] + '=' + ':param_blob', +
CONFIG_Table[ aCONFIG_SCHEDULES ] + '=' + ':schedules_blob'; + '
;' );
HSLmySQL.ADOQuery1.Parameters.ParamByName('param_blob').LoadFromStream( Mstream1, ftBlob );
HSLmySQL.ADOQuery1.Parameters.ParamByName('schedules_blob').LoadFromStream( Mstream2, ftBlob );
HSLmySQL.ADOQuery1.ExecSQL(); // => Boom, no exceptions catch nothing ..
and my program hangs.

If function not working in case of numeric characters

So i have used the following code
If (txtbedroom + txtkitchen + txtbathroom + txtlivingroom + 0) > 9 Or (txtbedroom + txtkitchen + txtbathroom + txtlivingroom + 0) < 7 Then
If MsgBox("Please ensure the number of rooms you entered is entered correctly.", vbYesNo) = vbNo Then
Exit Sub
End If
End If
even if the result of the following is less than 9 and greater than 7 the if function still gets satisfied... what can be done??
Anyway I solved the problem. I used a variable and the code CInt() like x = CInt(txtbedroom) to convert the text to number and then it worked...

Where can I find a "ESC/POS" Epson Barcode Test Program?

I am struggling to get an Epson "ESC/POS" printer to print barcodes (Using Delphi) and want to test if the printer is not faulty. Do you know where I can find a program to print a barcode in "ESC/POS"? I suppose as a last resort an OPOS program will also be OK.
Also, a demo Delphi Program that works will also be fine. All the Delphi snippets I have so far is not working.
The printer I am using is an Epson TM-L60II
I Have a full tests program written in Delphi 5 for the TMT88's but the source is abit big for here so here is the barcode bits
Please note that as its snippets from the full object some vars/functions may be missing
To get the barcode chars
{**
* #param a ean13 barcode numeric value
* #return the escpos code for the barcode print
* Description uses escpos code, return code needed to print a ean13 barcode
*}
function TPrintEscPosToPort.getBarcodeEscPosCode(l_ean13:String):String;
var
l_return:String;
begin
l_return := CHR(29) + 'k' + CHR(67) + CHR(12);
l_return := l_return + l_ean13; // Print bar code
l_return := l_return + l_ean13; // Print bar code number under thge barcode
Result := l_return
end;
to print to a printer
{**
* #param Printer Name, Item be printed, Cut the papers after the cut, #no of copies to print
* #return boolen, true if it printed
* Description prints a test page to the tysso printer
*}
function TPrintEscPosToPort.escPosPrint(const l_printer, l_textToPrint :String;l_cutPaper:Boolean=true;l_copies:integer=1): Boolean;
var
l_pPort,l_pName,l_tmp:String;
i,x:integer;
PrinterFile: TextFile;
begin
// set result to false so any thing other then a good print will be false
Result:= FALSE;
try
//Find if the printer exists, else set to defult -1
i := Printer.Printers.IndexOf(l_printer);
if (i > -1) then
begin
Printer.PrinterIndex := i;
l_pName := Printer.Printers[i]; //Get the printer name (incase its the defult and not the one passed)
l_pPort := Self.getPrinterPort(l_pName) ; // get the port name from the reg
end;
// If true add headers and footers to the passed text
if (Self.aPrintHeadersFooters) then
begin
l_tmp := Self.getHeader()
+ l_textToPrint + Self.GetFooter();
end
else
begin
l_tmp := l_textToPrint;
end;
//Send the Document To the printer
try
for x:= 1 to l_copies do //Print multi-copies
Begin
//Assign the file to a tmp file in the printer port
if (length(trim(l_pPort)) > 0) then AssignFile(PrinterFile,l_pPort)
else
begin
//only use if we cant get the port
//(may look bad as ctrl codes are still in place)
AssignPrn(PrinterFile);
l_tmp := Self.stripEscPos(l_tmp);
end;
Rewrite(PrinterFile);
try
//Send the passed Text to the printer
WriteLn(PrinterFile,l_tmp);
if (Self.aPrinterReset) then
WriteLn(PrinterFile,escReset); // Reset the printer alignment
if (l_cutPaper) then
WriteLn(PrinterFile,escFeedAndCut); //Cut the paper if needed
finally
CloseFile(PrinterFile);
Result:= true;
end;
end;
except
end;
except
end;
end;
Update
Here is a lost of control code constants from the code above, hopefully the names are descriptive enough.
const
escNewLine = chr(10); // New line (LF line feed)
escUnerlineOn = chr(27) + chr(45) + chr(1); // Unerline On
escUnerlineOnx2 = chr(27) + chr(45) + chr(2); // Unerline On x 2
escUnerlineOff = chr(27) + chr(45) + chr(0); // Unerline Off
escBoldOn = chr(27) + chr(69) + chr(1); // Bold On
escBoldOff = chr(27) + chr(69) + chr(0); // Bold Off
escNegativeOn = chr(29) + chr(66) + chr(1); // White On Black On'
escNegativeOff = chr(29) + chr(66) + chr(0); // White On Black Off
esc8CpiOn = chr(29) + chr(33) + chr(16); // Font Size x2 On
esc8CpiOff = chr(29) + chr(33) + chr(0); // Font Size x2 Off
esc16Cpi = chr(27) + chr(77) + chr(48); // Font A - Normal Font
esc20Cpi = chr(27) + chr(77) + chr(49); // Font B - Small Font
escReset = chr(27) + chr(64); //chr(27) + chr(77) + chr(48); // Reset Printer
escFeedAndCut = chr(29) + chr(86) + chr(65); // Partial Cut and feed
escAlignLeft = chr(27) + chr(97) + chr(48); // Align Text to the Left
escAlignCenter = chr(27) + chr(97) + chr(49); // Align Text to the Center
escAlignRight = chr(27) + chr(97) + chr(50); // Align Text to the Right
Get the Microsoft POS For .Net 1.11, it's got an SDK that includes a sample application that performs all the basic operations on POS hardware. I'm using it all the time to test that cash drawers work ok for example.
There's also a source code included (in .Net), so you can see how they do it.

Resources