FB_FileClose is only the first time busy - plc

I'm working with TwinCAT 3 and ST to save data from a socket connection. The sockets work and parts of the saving too, but not all of it. The first array I try to save works fine. But if i want to save another one, it fails. The FB_FileClose doesn't go bBusy.
IF reset THEN // I reset the FB after it saved one array.
bSuccess := FALSE;
iError := 0;
step := 1;
reset := FALSE;
MEMSET(ADR(saveArray), 0, SIZEOF(saveArray));
RETURN;
END_IF
CASE step OF
1:
IF path = '' THEN
bSuccess := FALSE;
iError := 12;
step := 1;
END_IF
fbFileOpen.sPathName := path;
fbFileOpen.nMode := FOPEN_MODEAPPEND OR FOPEN_MODEPLUS;
fbFileOpen.bExecute := TRUE;
fbFileOpen.tTimeout := T#2S;
fbFileOpen();
step := 2;
2:
fbFileOpen(bExecute := FALSE);
IF NOT fbFileOpen.bBusy AND NOT fbFileOpen.bError THEN
step := 3;
ELSE
iError := fbFileOpen.nErrId;
END_IF
3:
fbWriteFile.hFile := fbFileOpen.hFile;
fbWriteFile.bExecute := TRUE;
fbWriteFile.pWriteBuff := ADR(saveArray);
fbWriteFile.cbWriteLen := SIZEOF(saveArray);
fbWriteFile.tTimeout := T#2S;
fbWriteFile();
step := 4;
4:
fbWriteFile(bExecute := FALSE);
IF NOT fbWriteFile.bBusy AND NOT fbWriteFile.bError THEN
step := 5;
END_IF
5:
fbCloseFile.hFile := fbFileOpen.hFile;
fbCloseFile.bExecute := TRUE;
fbCloseFile.tTimeout := T#3S;
fbCloseFile();
IF fbCloseFile.bBusy THEN //Gets suck here at the second run. And if I remove it, the FB doesn't get busy and doesn't close my hFile.
step := 6;
END_IF
6:
fbCloseFile(bExecute := FALSE);
IF NOT fbCloseFile.bBusy AND NOT fbCloseFile.bError THEN
bSuccess := TRUE;
ELSE
iError := fbCloseFile.nErrId;
END_IF
END_CASE
I also noticed that FB_FileOpen opens the same hFile two times in a row. The second one of it can't get closed from the FB_FileClose. The next run it gets a new hFile and then it can save the data. Next one it can't, and so on. What's my error in this one?
Thank you!

Found the solution by myself after a bit of hackaround. Before I set all the parameters for FB_FileOpen, FB_FileWrite and FB_FileClose I set the execute to false like this:
1:
IF path = '' THEN
bSuccess := FALSE;
iError := 12;
step := 1;
END_IF
fbFileOpen(bExecute := FALSE); // Set this to false before.
fbFileOpen.sPathName := path;
fbFileOpen.nMode := FOPEN_MODEAPPEND OR FOPEN_MODEPLUS;
fbFileOpen.bExecute := TRUE;
fbFileOpen.tTimeout := T#2S;
fbFileOpen();
step := 2;
Now it's working.

Related

Delphi 10.4. Fast Report 6. REST application. Print Failure

I have created a REST server in Delphi using WebBroker. My intention is to use it as a label printer. A client prepares and sends a JSON request detailing the printer name, Fast Report & variables. The server reads the JSON, creates a tFrxReport object loads the requisite report and populates the variables.
This all works admirably, except it will not print to a physical printer. If I select OneNote as my destination, the label is saved to the desktop. If I select a network attached printer, no label emerges.
I have tried PrintOptions.ShowDialog:=True The print dialog shows, indicating the correct printer, but it does not print.
If anyone has any experience, could you point me in the right direction please?
function processJson(itm : sat; jtr : tJsonTextReader): sat;
var
idx : integer;
//itm : sat; // simple array type [idx, 'val1', 'val2']
begin
setlength(itm,0);
idx:=0;
while jtr.Read do
begin
if jtr.TokenType = tJsonToken.PropertyName then
begin
setlength(itm, length(itm)+1);
itm[idx].st_idx := idx;
itm[idx].st_code := jtr.Value.ToString; // property name
jtr.Read;
itm[idx].st_desc := jtr.Value.AsString; // property value
inc(idx);
end;
end;
processJson := itm;
end;
function getPrinterInfo(pnam: string):printinfo_type;
var
ptr : printinfo_type;
idx : integer;
begin
ptr.idx := -1; //default printer
ptr.name := trim(pnam);
for idx := 0 to Printer.Printers.Count - 1 do
if AnsiContainsText(Printer.Printers[idx], ptr.name) then
ptr.idx := idx;
result := ptr;
end;
procedure Ttfdq.tfdqactLabelAction(Sender: TObject; Request: TWebRequest;
Response: TWebResponse; var Handled: Boolean);
var
post : simpleArray_type;
pdx, idx, iitm : integer;
jtr : tJsonTextReader;
sr : tStringReader;
pish : string;
fr : tFrxReport;
thePtr : printinfo_type;
itm : sat;
tstprt : boolean;
begin
d.myHost := 'http://' + Request.host + ':' + intToStr(Request.ServerPort);
d.hostIP := Request.host;
d.Request := Request;
d.Response := Response;
d.remAddr := Request.RemoteAddr;
post := explode(Request.Content);
tstprt := false;
pdx := isset(post, 'json');
pish:='';
if (pdx >=0) then
begin
sr := tStringReader.Create(post[pdx].st_desc);
jtr := tJsonTextReader.Create(sr);
while jtr.read do
begin
if jtr.TokenType = tJsonToken.StartObject then
itm := processJson(itm, jtr);
end;
if fileexists(itm[2].st_desc) then
begin
thePtr := getPrinterInfo(itm[1].st_desc);
fr := tFrxReport.Create(nil);
fr.LoadFromFile(itm[2].st_desc);
// pre load any vars so report does not fail
for idx := 0 to fr.Variables.Count-1 do
fr.Variables.Items[iitm].Value := frText('');
for idx := 4 to High(itm) do
begin
pish := pish + 'index of '+itm[idx].st_code+' = '+ intToStr (fr.Variables.IndexOf(itm[idx].st_code))+'<br>';
iitm := fr.Variables.IndexOf(itm[idx].st_code);
if iitm > -1 then
fr.Variables.Items[iitm].Value := frText(itm[idx].st_desc);
end;
if fr.PrepareReport then
begin
//fr.ShowPreparedReport;
fr.PrintOptions.Printer := thePtr.name;
fr.PrintOptions.PrnOutFileName := 'Trace Label';
fr.PrintOptions.ShowDialog := tstprt;
fr.ShowProgress := tstprt;
fr.Print;
end;
fr.Free;
end;
Response.Content := pish ;
end
else
begin
Response.Content := '<html>' +
'<head><title>Label List</title></head>' +
'<body>This is only used by print serve clients</p>'+
'</body>' +
'</html>';
end;
end;
The problem lies here:
fr.PrintOptions.PrnOutFileName := 'Trace Label';
I erroneously thought that would add a description in the print queue. What it actually did is send the report into limbo :)

Delphi - Rich edit doesn't show on dynamically created form

I've dynamically created a Form in my program, and it works and shows perfectly, but the RichEdit I've also dynamically created doesn't want to show on the Form at all. How can I show the RichEdit on the Form?
Code I'm using:
procedure TfrmPuntehou.lblAbbClick(Sender: TObject);
var
frmAbb: TForm;
redAbbreviations: TRichEdit;
begin
//opens abbreviations
frmAbb := TForm.Create(nil);
redAbbreviations := TRichEdit.Create(nil);
try
with frmAbb do
begin
Width := 400;
Height := 400;
Caption := 'Abbreviations';
Position := poOwnerFormCenter;
ShowModal;
end;
with redAbbreviations do
begin
Parent := frmAbb;
Width := 300;
Height := 353;
redAbbreviations.Paragraph.TabCount := 2;
redAbbreviations.Paragraph.Tab[0] := 30;
redAbbreviations.Paragraph.Tab[1] := 60;
Lines.Add('DEV'+#9+'='+#9+'SWD Development');
Lines.Add('1660'+#9+'='+#9+'1660s');
Lines.Add('2.1'+#9+'='+#9+'2.1s');
Lines.Add('MIN'+#9+'='+#9+'Minis');
Lines.Add('SR'+#9+'='+#9+'Stockrods');
Lines.Add('PR'+#9+'='+#9+'Pinkrods');
Lines.Add('HR'+#9+'='+#9+'Hotrods');
Lines.Add('HM'+#9+'='+#9+'Heavy Metals');
Lines.Add('V8'+#9+'='+#9+'V8s');
Lines.Add('MA'+#9+'='+#9+'Midgets A');
Lines.Add('MB'+#9+'='+#9+'Midgets B');
Lines.Add('SP'+#9+'='+#9+'Sprints');
Lines.Add('CRO'+#9+'='+#9+'Crosskarts');
Lines.Add('LM'+#9+'='+#9+'Late Models');
Font.Size := 13;
end;
finally
frmAbb.Free;
end;
end;
Move the ShowModal from the initialization part of the frmAbb to the end of the code, just before the finally statement.
procedure TForm1.Button1Click(Sender: TObject);
var
frmAbb: TForm;
redAbbreviations: TRichEdit;
begin
//opens abbreviations
frmAbb := TForm.Create(nil);
try
redAbbreviations := TRichEdit.Create(frmAbb);
with frmAbb do
begin
Width := 400;
Height := 400;
Caption := 'Abbreviations';
Position := poOwnerFormCenter;
end;
with redAbbreviations do
begin
Parent := frmAbb;
Width := 300;
Height := 353;
redAbbreviations.Paragraph.TabCount := 2;
redAbbreviations.Paragraph.Tab[0] := 30;
redAbbreviations.Paragraph.Tab[1] := 60;
Lines.Add('DEV'+#9+'='+#9+'SWD Development');
Lines.Add('1660'+#9+'='+#9+'1660s');
Lines.Add('2.1'+#9+'='+#9+'2.1s');
Lines.Add('MIN'+#9+'='+#9+'Minis');
Lines.Add('SR'+#9+'='+#9+'Stockrods');
Lines.Add('PR'+#9+'='+#9+'Pinkrods');
Lines.Add('HR'+#9+'='+#9+'Hotrods');
Lines.Add('HM'+#9+'='+#9+'Heavy Metals');
Lines.Add('V8'+#9+'='+#9+'V8s');
Lines.Add('MA'+#9+'='+#9+'Midgets A');
Lines.Add('MB'+#9+'='+#9+'Midgets B');
Lines.Add('SP'+#9+'='+#9+'Sprints');
Lines.Add('CRO'+#9+'='+#9+'Crosskarts');
Lines.Add('LM'+#9+'='+#9+'Late Models');
Font.Size := 13;
end;
frmAbb.ShowModal;
finally
frmAbb.Free;
end;
end;
You forgot to make it visible:
redAbbreviations.Visible := TRUE;
And you show the form modal before setting properties to the RichEdit.
Here is the correct reformatted code:
procedure TForm1.Button1Click(Sender: TObject);
var
frmAbb : TForm;
redAbbreviations : TRichEdit;
begin
// opens abbreviations
frmAbb := TForm.Create(nil);
try
redAbbreviations := TRichEdit.Create(frmAbb);
frmAbb.Width := 400;
frmAbb.Height := 400;
frmAbb.Caption := 'Abbreviations';
frmAbb.Position := OwnerFormCenter;
redAbbreviations.Parent := frmAbb;
redAbbreviations.Width := 300;
redAbbreviations.Height := 353;
redAbbreviations.Paragraph.TabCount := 2;
redAbbreviations.Paragraph.Tab[0] := 30;
redAbbreviations.Paragraph.Tab[1] := 60;
redAbbreviations.Lines.Add('DEV'+#9+'='+#9+'SWD Development');
redAbbreviations.Lines.Add('1660'+#9+'='+#9+'1660s');
redAbbreviations.Lines.Add('2.1'+#9+'='+#9+'2.1s');
redAbbreviations.Lines.Add('MIN'+#9+'='+#9+'Minis');
redAbbreviations.Lines.Add('SR'+#9+'='+#9+'Stockrods');
redAbbreviations.Lines.Add('PR'+#9+'='+#9+'Pinkrods');
redAbbreviations.Lines.Add('HR'+#9+'='+#9+'Hotrods');
redAbbreviations.Lines.Add('HM'+#9+'='+#9+'Heavy Metals');
redAbbreviations.Lines.Add('V8'+#9+'='+#9+'V8s');
redAbbreviations.Lines.Add('MA'+#9+'='+#9+'Midgets A');
redAbbreviations.Lines.Add('MB'+#9+'='+#9+'Midgets B');
redAbbreviations.Lines.Add('SP'+#9+'='+#9+'Sprints');
redAbbreviations.Lines.Add('CRO'+#9+'='+#9+'Crosskarts');
redAbbreviations.Lines.Add('LM'+#9+'='+#9+'Late Models');
redAbbreviations.font.Size :=13;
redAbbreviations.Visible := TRUE;
frmAbb.ShowModal;
finally
frmAbb.Free;
end;
end;

Exception raised when setting Text property of TEdit in custom component (Lazarus)

Using: Lazarus 1.2.0; Windows 32-bit application
I have created a custom component derived from TCustomPanel and contains some TEdit controls.
At runtime, when I try to set the Text property of an edit control in my component, I get a runtime error.
This is the error:
Project project1 raised exception class 'External: SIGSEGV'.
In file '.\include\control.inc' at line 3246:
GetTextMethod := TMethod(#Self.GetTextBuf);
I Googled and could not find anybody else reporting this error specifically when setting the Text property of TEdit.
This leads me to believe that I did something wrong when writing the component. Please check my code and point out what is wrong and how to fix it. TIA!
Code follows:
unit uEditPanel;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
type
{ TEditPanel }
TEditPanel = class(TCustomPanel)
Edit0: TCustomEdit;
Edit1: TCustomEdit;
Edit2: TCustomEdit;
Edit3: TCustomEdit;
Edit4: TCustomEdit;
private
{ Private declarations }
function GetEdit0Text: string;
procedure SetEdit0Text(AText: string);
function GetEdit1Text: string;
procedure SetEdit1Text(AText: string);
function GetEdit2Text: string;
procedure SetEdit2Text(AText: string);
function GetEdit3Text: string;
procedure SetEdit3Text(AText: string);
function GetEdit4Text: string;
procedure SetEdit4Text(AText: string);
protected
{ Protected declarations }
public
{ Public declarations }
procedure CreateWnd; override;
published
{ Published declarations }
property Edit0Text: string read GetEdit0Text write SetEdit0Text;
property Edit1Text: string read GetEdit1Text write SetEdit1Text;
property Edit2Text: string read GetEdit2Text write SetEdit2Text;
property Edit3Text: string read GetEdit3Text write SetEdit3Text;
property Edit4Text: string read GetEdit4Text write SetEdit4Text;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard', [TEditPanel]);
end;
{ TEditPanel }
function TEditPanel.GetEdit0Text: string;
begin
Result := Edit0.Text;
end;
procedure TEditPanel.SetEdit0Text(AText: string);
begin
Edit0.Text := AText;
end;
function TEditPanel.GetEdit1Text: string;
begin
Result := Edit1.Text;
end;
procedure TEditPanel.SetEdit1Text(AText: string);
begin
Edit1.Text := AText;
end;
function TEditPanel.GetEdit2Text: string;
begin
Result := Edit2.Text;
end;
procedure TEditPanel.SetEdit2Text(AText: string);
begin
Edit2.Text := AText;
end;
function TEditPanel.GetEdit3Text: string;
begin
Result := Edit3.Text;
end;
procedure TEditPanel.SetEdit3Text(AText: string);
begin
Edit3.Text := AText;
end;
function TEditPanel.GetEdit4Text: string;
begin
Result := Edit4.Text;
end;
procedure TEditPanel.SetEdit4Text(AText: string);
begin
Edit4.Text := AText;
end;
procedure TEditPanel.CreateWnd;
begin
inherited CreateWnd;
Caption := EmptyStr;
Height := 117;
Width := 289;
BevelOuter := bvNone;
ClientHeight := 117;
ClientWidth := 289;
Edit0 := TCustomEdit.Create(Self);
Edit1 := TCustomEdit.Create(Self);
Edit2 := TCustomEdit.Create(Self);
Edit3 := TCustomEdit.Create(Self);
Edit4 := TCustomEdit.Create(Self);
Edit0.Left := 0;
Edit0.Height := 21;
Edit0.Top := 0;
Edit0.Width := 288;
//Edit0.BorderStyle := bsNone;
Edit0.TabOrder := 0;
Edit1.Left := 0;
Edit1.Height := 21;
Edit1.Top := 24;
Edit1.Width := 288;
// Edit1.BorderStyle := bsNone;
Edit1.TabOrder := 1;
Edit1.Font.Color := clGray;
Edit2.Left := 0;
Edit2.Height := 21;
Edit2.Top := 48;
Edit2.Width := 288;
// Edit2.BorderStyle := bsNone;
Edit2.TabOrder := 2;
Edit2.Font.Color := clGray;
Edit3.Left := 0;
Edit3.Height := 21;
Edit3.Top := 72;
Edit3.Width := 288;
//Edit3.BorderStyle := bsNone;
Edit3.TabOrder := 3;
Edit3.Font.Color := clGray;
Edit4.Left := 0;
Edit4.Height := 21;
Edit4.Top := 96;
Edit4.Width := 288;
//Edit4.BorderStyle := bsNone;
Edit4.TabOrder := 4;
Edit4.Font.Color := clGray;
Edit0.Parent := Self;
Edit1.Parent := Self;
Edit2.Parent := Self;
Edit3.Parent := Self;
Edit4.Parent := Self;
Edit0.SetSubComponent(True);
Edit1.SetSubComponent(True);
Edit2.SetSubComponent(True);
Edit3.SetSubComponent(True);
Edit4.SetSubComponent(True);
end;
end.
Solved. Answer posted by user JuhaManninen on the Lazarus support forum:
"You have no constructor in your class. Replace CreateWnd with a
constructor."

Delphi: Creating a TComboBox in a dynamically created form at runtime

Okay, I am working in a project that was originally done in D7. And I am doing double duty here as I am working on fixing bugs in the original code and attempting to port it over to XE3/4. Kinda hard when the original author used some none-open source kits for the project.
But anyways, the app is a scripting/macroing program. As part of the custome scripting/macroing language. There is a ability to create very simple basic forms for user input. The forms are created dynamically at runtime based on the script/macro the script/macro author has created. I have already fixed some bugs in the code for the creation of the forms. But, there is one that I just can not figure out.
When creating a TComboBox for the parent form and setting the Text property AT component creation. The text in the Text property is not displayed.
Here is the code to create the form:
procedure CreateForm(var wFrm: TForm; sName: String);
var
iLoop, iPos, iLen: Integer;
iFormHeight, iFormWidth: Integer;
lh, hresult1, hresult2: Integer;
sWork, sWork2, sLine, CmdName: String;
lstForm, lst: TStringList;
pnl: TPanel;
begin
iFormHeight := 80;
iFormWidth := 400;
hresult1 := 0;
lst := TStringList.Create;
iLoop := lstForms.IndexOf(Trim(UpperCase(sName)));
if iLoop < 0 then
begin
AbortError('Form "' + sName + '" could not be found!');
Exit;
end;
lstForm := TStringList(lstForms.Objects[iLoop]);
for iLoop := 0 to lstForm.Count - 1 do
begin
sLine := lstForm[iLoop];
iPos := Pos('=', sLine);
iLen := Length(sLine);
if iPos = 0 then
continue;
CmdName := Uppercase(Trim(Copy(sLine, 1, iPos - 1)));
sWork2 := Trim(Copy(sLine, iPos + 1, iLen));
if CmdName = 'FORMCAPTION' then
begin
with wfrm do
begin
Caption := Trim(Copy(sLine, iPos + 1, iLen));
Name := Trim(sName);
Height := iFormHeight;
Width := iFormWidth;
Tag := 10;
BorderStyle := bsSizeable;
BorderIcons := [biSystemMenu];
Position := poDesktopCenter;
pnl := TPanel.Create(wfrm);
with pnl do
begin
Parent := wfrm;
Caption := '';
Align := alBottom;
BevelInner := bvNone;
BevelOuter := bvNone;
Height := 30;
end;
with TButton.Create(wfrm) do
begin
Parent := pnl;
Caption := '&OK';
Default := True;
ModalResult := mrOK;
Left := 235;
Top := 0;
end;
with TButton.Create(wfrm) do
begin
Parent := pnl;
Caption := '&Cancel';
Cancel := True;
ModalResult := mrCancel;
Left := 310;
Top := 0;
end;
pnl := TPanel.Create(wfrm);
with pnl do
begin
Parent := wfrm;
Caption := '';
Align := alClient;
BevelInner := bvRaised;
BevelOuter := bvNone;
BorderWidth := 5;
end;
end;
end
else
begin
lst.Clear;
StringToList(sWork2, lst, ':');
if UpperCase(lst[0]) = 'EDITBOX' then
CreateEditBox
else if UpperCase(lst[0]) = 'CHECKBOX' then
CreateCheckBox
else if UpperCase(lst[0]) = 'COMBOBOX' then
CreateComboBox
else if UpperCase(lst[0]) = 'LABEL' then
CreateLabel;
end;
end;
with wfrm do
begin
if hresult1 > 1 then
hresult2 := 5
else
hresult2 := 9;
Tag := Tag + hresult2;
Height := Height + hresult2;
end;
lst.Free;
end;
And here is the specific code to create the TComboBox, w/ TLabel, for the form:
procedure CreateComboBox;
var
iPos: Integer;
begin
with TLabel.Create(wfrm) do
begin
Parent := pnl;
Caption := lst[1];
Left := 15;
if hresult1 > 1 then
hresult2 := 5 * hresult1
else
hresult2 := 3 * hresult1;
Top := wfrm.Tag + hresult2;
Name := 'lbl' + CmdName;
Width := 150;
WordWrap := True;
AutoSize := True;
lh := Height;
end;
hresult1 := Trunc(lh/13);
with TComboBox.Create(wfrm) do
begin
Parent := pnl;
Left := 170;
Width := 200;
if hresult1 > 1 then
hresult2 := 5 * hresult1
else
hresult2 := 3 * hresult1;
Top := wfrm.Tag + hresult2;
Style := csDropDownList;
Name := UpperCase(CmdName);
Text := 'Test Text';
sWork := lst[3];
lst.Clear;
StringToList(sWork, lst, ',');
for iPos := 0 to lst.Count - 1 do
lst[iPos] := lst[iPos];
Items.Assign(lst);
// ItemIndex := 0;
end;
wfrm.Tag := wfrm.Tag + ((hresult1 * 13)+ 13);
wfrm.Height := wfrm.Height + ((hresult1 * 13)+ 13);
TComboBox(wfrm
end;
NOTE: the above procedure is a child procedure of the CreateForm procedure.
The app uses TStringList lists to store the form definition at script/macro runtime. Then the above code retrieves that information to create to form when the author wants the form to be shown. And then creates the form and places the form object into another temporary TStringList list prior to being shown. This is done so that when the user runs the script/macro and enters the information/settings as requested in the form. The author may retrieve the requested information/settings from the form before the form is destroyed.
The form is deleted (if previously created) from tmp TStringList list, created, stored in tmp TStringList list, and shown modally with the following code:
iPos := lstForms.IndexOf(UpperCase(sWVar2));
if iPos < 0 then
begin
AbortError('Could not find form "' + Trim(sWVar2) + '" defined!');
Exit;
end;
iPos := lstFormsTMP.IndexOf(UpperCase(sWVar2));
if iPos > -1then
begin
TForm(lstFormsTMP.Objects[iPos]).Free;
lstFormsTMP.Delete(iPos);
frm.Free;
iPos := lstFormsTMP.IndexOf(UpperCase(sWVar2));
if iPos > -1 then
begin
AbortError('Form "' + Trim(sWVar2) + '" was not removed from the lstFormsTMP TStringList.');
Exit;
end;
end;
frm := TForm.Create(frmMain);
CreateForm(frm, sWVar2);
lstFormsTMP.AddObject(Uppercase(sWVar2), frm);
end;
iPos := lstFormsTMP.IndexOf(UpperCase(sWVar2));
if iPos < 0 then
begin
AbortError('Could not find form "' + Trim(sWVar2) + '" defined!');
Exit;
end;
hndHold := SwitchToHandle(frmMain.Handle);
try
Result := TForm(lstFormsTMP.Objects[iPos]).ShowModal = mrOK;
finally
SwitchToHandle(hndHold);
end;
With the above sets of code the form defined in the running script is created and shown, without to many bugs/errors. But, even though I have hardcoded the text for the TComboBox.Text property. It is not shown. Can anyone shed some lite on why this is the case for me? All other form components, TCheckBox, TEditBox, TLabel, are displayed without any issues, so far. It is just the TComboBox that is causing me to scratch my head in confusion.
NOTE: Eventually the TComboBox.Text property will be dynamically set based on the authors setting for that property in the form component's definition.
Thanks in advance.
EDITED 8/18/2013, to include the following:
The original code also includes the ability to save/load the form component's settings by way of the TIniFile object. The following code is used to save the setting for the TComboBox:
if frm.Components[i] is TCombobox then
iniWork.WriteString(frm.Name, TCombobox(frm.Components[i]).Name, TCombobox(frm.Components[i]).Text)
else
and the following to load the TComboBox setting:
if frm.Components[i] is TCombobox then
begin
TCombobox(frm.Components[i]).ItemIndex := TCombobox(frm.Components[i]).Items.IndexOf(
iniWork.ReadString(frm.Name, TCombobox(frm.Components[i]).Name, TCombobox(frm.Components[i]).Text));
end
With the above code it looks to me like the setting is being save from and loaded back into the TComboBox's Text property. Now when the TComboBox setting is loaded, the form is changed after it has been created and placed, as an object, into the tmp TStringList list and prior to being shown modally. Yet, when the form is shown the Text property, as set by the above load code above, is shown.
It is because of the above that I am confused. Why does it work at this point, after the form is created. Yet not when the form is created?
This is a drop down list because you set the style to csDropDownList. That means that the edit control of the combo box can only display items that are contained in its list control.
For a drop down list combo, setting the Text property has no effect. Instead of using the Text property, you should be specifying ItemIndex.

How to prevent forms moving of screen

I use the following helper for preventing forms moving of screen and it is most of the time working OK. But if I open a wsNormal form in a MDI app then the form might show up of the area where it is supposed to be. I can then just move it a bit and then the unit here takes over and moves it in place.
My question is now: how can I either prevent this from happening or send a message to the form saying it is moving so the unit her can do its job.
unit U_FormsMove;
interface
uses
Messages, Windows, Forms;
{$M+}
type
TForm = class(Forms.TForm)
private
protected
procedure WMMoving(var message : TWMMoving); message WM_MOVING;
published
public
end;
implementation
function GetMovementArea: TRect;
var
MovementRect: TRect;
begin
if Application.MainForm.FormStyle = fsMDIForm then
Windows.GetWindowRect(Application.MainForm.ClientHandle, MovementRect)
else
SystemParametersInfo(SPI_GETWORKAREA, 0, #MovementRect, 0);
if MovementRect.Top < 150 then
MovementRect.Top := 150;
MovementRect.Top := MovementRect.Top + 5;
MovementRect.Left := MovementRect.Left + 5;
MovementRect.Right := MovementRect.Right - 5;
MovementRect.Bottom := MovementRect.Bottom - 5;
Result := MovementRect;
end;
{ TFormHelper }
procedure TForm.WMMoving(var Message: TWMMoving);
var
rec: ^TRect;
wrk: TRect;
begin
wrk := GetMovementArea;
rec := Pointer(Message.DragRect);
if rec^.Left < wrk.Left then
begin
rec^.Right := rec^.Right - (rec^.Left - wrk.Left);
rec^.Left := wrk.Left;
end
else if rec^.Right > wrk.Right then
begin
rec^.Left := rec^.Left - (rec^.Right - wrk.Right);
rec^.Right := wrk.Right;
end;
if rec^.Top < wrk.Top then
begin
rec^.Bottom := rec^.Bottom - (rec^.Top - wrk.Top);
rec^.Top := wrk.Top;
end
else if rec^.Bottom > wrk.Bottom then
begin
rec^.Top := rec^.Top - (rec^.Bottom - wrk.Bottom);
rec^.Bottom := wrk.Bottom;
end;
end;
end.