How to showmodal a form or getting value from same form in TTabSheet? - vcl

I have a form that I display in two different ways. First one is child of TTabSheet in TPageControl. I don't need to collect any data and it works fine.
First way
with TTabSheet.Create(APageControl) do
begin
PageControl := APageControl;
Caption := 'Child Form Caption Info';
APageControl.ActivePageIndex := PageIndex;
end;
with TMyDefinitionForm.CreateFor(Application, 'DEF_TYPE', 'Child Form Caption Info') do
begin
Parent := APageControl.Pages[APageControl.ActivePageIndex];
Align := alClient;
Name := 'ChildFormName';
Show;
end;
Second one is creating by different detail form and should be returned some needed values from same form. But when I create this form as first one, I can't display form as ShowModal in TTabSheet. (It can't be active or focused)
Second way
var
AComponent: TComponent;
begin
{This is different detail form and its owner is DashboardForm which has TPageControl}
AComponent := (Self.Owner.FindComponent('APageControl') as TPageControl);
with TTabSheet.Create(AComponent) do
begin
PageControl := (AComponent as TPageControl);
Caption := 'Child Form Caption Info';
(AComponent as TPageControl).ActivePageIndex := PageIndex;
end;
with TMyDefinitionForm.CreateFor(Self, 'DEF_TYPE', 'Child Form Caption Info') do
begin
Parent := (AComponent as TPageControl).Pages[(AComponent as TPageControl).ActivePageIndex];
Name := 'ChildFormName';
Show; { If I change this to ShowModal, I can't click to my form }
end;
txtFieldOne.Text := DataModuleObject.Field; {sample usage}
txtFieldTwo.Text := DataModuleObject.Field2; {sample usage}
SomeVariables:= DataModuleObject.Field3; {sample usage}
end;
Problem: I have a DataModule that has data objects for general usage. When I create this child form, I have to set some value to those objects and after closing child form, those data should be set to my first form. To do this, I always used ShowModal, then in next lines I set those values to my first form. But now I can't open ShowModal in TTabSheet.
Question: Is there any way to get those values from child form?
Bonus Question: I can use ShowModal then I can get those values, if I just create that form. Should I create form as normal in TTabSheet without set the Parent Control?
Note: using XE10.1 Berlin

Related

Load image as blob into ListView

I am trying to load an image as blob into a ListView.
Table:
CREATE TABLE [Pictures](
[PicId] INT,
[UsersImage] BLOB);
Code:
procedure LoadFromBlob;
var
BlobStream: TStream;
begin
Form4.FDConnection1.Connected := True;
try
Form4.FDQuery1.Active := True;
Form4.viewimgquery.Active := True;
Form4.FDQuery1.Open;
Form4.viewimgquery.Open;
Form4.viewimgquery.First;
while (not Form4.viewimgquery.EOF) do
begin
// access a stream from a blob like this
BlobStream := Form4.viewimgquery.CreateBlobStream
(Form4.viewimgquery.FieldByName('UsersImage'), TBlobStreamMode.bmRead);
// access a string from a field like this
if (Form4.viewimgquery.FieldByName('PicId')
.AsInteger = Form4.FDQuery1.FieldByName('ID').AsInteger) then
begin
// load your blob stream data into a control
Form4.viewimage.Bitmap.LoadFromStream(BlobStream);
Form4.ListView1.items.Add();
BlobStream.Free;
Form4.viewimgquery.Next;
end;
end;
except
on e: Exception do
begin
// ShowMessage(e.Message);
end;
end;
Form4.FDConnection1.Connected := False;
end;
Query:
SELECT *
FROM PICTURES
WHERE PICID = :PicId
If I change it to select * from pictures and set query to active at design time I see all images loaded into the ListView so my live bindings are set up correctly. But when I call the procedure nothing is loaded into the ListView.

Build a query on the selected record , position of the dataset pointer

to display the content of a geometry/spatial field I made a small component. This component does it's job when I provide all the information to query the table correctly.
tablename
fieldname of the gemoetry field
fieldname of a field to select the correct element by a query
a connection to connect the query to the correct database on my server
a datasource to display other elements of my table for reference
as my component should be similliar to all the other dbmemo, dbedit ... VCL components, I do not want to share
a) fieldname of a field to select the correct element by a query
and if possible also remove from parameter transfer to my component
b) the connection
here come my current working solution and need help on a) and b)
unit Unit_DBmemoSpatial;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB ;
type
TDBmemoSpatial = class(TMemo)
private
{ Private-Deklarationen }
Fdatasource : Tdatasource ;
FConnection : TADOConnection;
FdataField : String;
procedure Setdatasource(const Value: Tdatasource);
procedure SetdataField(const Value: String);
procedure AfterSCROLL(DataSet: TDataSet);
protected
{ Protected-Deklarationen }
public
{ Public-Deklarationen }
published
{ Published-Deklarationen }
property Connection : TADOConnection read FConnection write FConnection ;
property datasoure : Tdatasource read Fdatasource write Setdatasource ;
property dataField : String read FdataField write SetdataField ;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('TOOLS', [ TDBmemoSpatial]);
end;
{ TDBmemoSpatial }
procedure TDBmemoSpatial.AfterSCROLL(DataSet: TDataSet);
var aQuery : TADOQuery ;
SQLSTR : String ;
RIndex : Integer ;
begin
/// this will only work on my table , not for others !!!!!
RIndex := Fdatasource.DataSet.FieldByName('MyrecordIndex').AsInteger;
self.Lines.Clear;
self.Lines.Add( 'DBCOMP' + TimetoStr(now) );
aQuery := TADOQuery.Create(nil);
try
aQuery.Connection := FConnection;
SQLSTR := 'SELECT ' + FdataField+'.STAsText() FROM ' + 'MyTable' + ' where MyrecordIndex=' + IntToStr(RIndex);
aQuery.SQL.Add(SQLSTR);
aQuery.Open;
self.Lines.Add( 'record affected ' + IntToStr(aQuery.RecordCount) );
self.Lines.Add( 'Text ' + (aQuery.Fields[0].asString) );
finally
aQuery.Free;
end;
end;
procedure TDBmemoSpatial.SetdataField(const Value: String);
begin
FdataField := Value;
end;
procedure TDBmemoSpatial.Setdatasource(const Value: Tdatasource);
begin
Fdatasource := Value;
Fdatasource.DataSet.AfterScroll := AfterSCROLL;
end;
end.
the calling code for my component goes like this
dbmsptl1.Connection := FCon;
dbmsptl1.datasoure := Fdatasource;
dbmsptl1.dataField :='geometry_by_Fieldname';

Delphi load image save as blob in a sql database

I'm trying to load a Image control from a image blob saved previously in a sql database.I have testd so many ways and i can't make it work. The image blob is saved as:
qry.SQL.Text := 'update tbl set pic = :blobVal where id = :idVal';
qry.Parameters.ParamByName('blobVal').LoadFromFile('c:\sample.jpg', ftBlob);
qry.Parameters.ParamByName('idVal').Value := 1;
any suggestion?
There a a lot of treads here about loading images to as database, but I did not find one with update or insert parameters.
You might simply assign a graphic object to your parameter.
If you want to store different graphic types you should add a column
keeping the Information which kind of graphic should be stored (e.g. jpeg,bmp,png).
to be able to create the needed TGraphic class descendant if you want to retrieve the picture from the database.
uses jpeg, pngimage;
type
TitTYPES=(itJPG,itPNG,itBMP);
procedure TDEMO.Button1Click(Sender: TObject);
var
jp:TJpegimage;
g:TGraphic;
begin
jp:=TJpegimage.Create;
try
ads.Close;
jp.LoadFromFile('C:\Bilder1\PIC.jpg');
ads.SQL.Text := 'Insert into IMGBlob (ID,Blob,typ) Values (:ID,:BLOB,:typ)';
ads.Parameters[0].Value := 1;
ads.Parameters[1].Assign(jp);
ads.Parameters[2].Value := itJPG;
ads.ExecSQL;
ads.SQL.Text := 'Select * from IMGBlob where ID=:ID';
ads.Parameters[0].Value := 1;
ads.Open;
try
case TitTYPES(ads.FieldByName('typ').AsInteger) of
itJPG: g:=TJpegimage.Create;
itPNG: g:=TPNGImage.Create;
itBMP: g:=TBitmap.Create;
end;
g.Assign(ads.FieldByName('Blob'));
Image1.Picture.Assign(g);
finally
g.Free;
end;
finally
jp.Free;
end;
end;
To load a BLOB field into an image, you need to use TDataSet.CreateBlobStream.
var
Stream: TStream;
JPG: TJpegImage;
begin
JPG := TJpegImage.Create;
try
Stream := Qry.CreateBlobStream(Qry.FieldByName('BLOBVAL'), bmRead);
try
JPG.LoadFromStream(Stream);
finally
Stream.Free; // edited
end;
finally
JPG.Free;
end;
end;
To store the image back, you'll need to do the reverse:
var
Stream: TBlobStream;
Jpg: TJpegImage;
begin
Jpg := TJpegImage.Create;
try
Jpg.Assign(Image1.Picture.Graphic);
// Assign other query parameters here
Stream := Qry.CreateBlobStream(Qry.FieldByName('BLOBVAL'), bmWrite);
try
Jpg.SaveToStream(Stream);
Qry.ExecSQL;
finally
Stream.Free;
end;
finally
Jpg.Free;
end;
end;
TDBImage is only designed to work with bitmaps (when the field is ftGraphic), so it won't work with JPEG images directly. The easiest thing to do is to load the blob as a JPEG, and assign it to a standard TImage.Picture.Graphic in an event handler for the dataset (such as it's AfterScroll event).
save to db:
var
ms:tmemorystream;
Begin
ms:=tmemorystream.create;
ms.position:=0;
image1.picture.bitmap.savetostream(ms);
ms.position:=0;
with yourfield as tblobfield do
loadfromstream(ms);
freeandnil(ms);
end;
Load from db:
var
ms:tmemorystream;
Begin
ms:=tmemorystream.create;
ms.position:=0;
with yourfield as tblobfield do
savetostream(ms);
ms.position:=0;
image1.picture.bitmap.loadfromstream(ms);
freeandnil(ms);
end;
It does not work with all graphic types like PNG etc.
This one does work on PNG as well:
var mBitmap : TGraphic;
var mStream : TStream;
var mClass : TGraphicClass;
begin
mStream := Query.CreateBlobStream(Query.FieldByName('yourBlobfield'), bmRead);
mClass := GetGraphicClassForFileExtension(mStream.ReadAnsiString);
mBitmap := mClass.Create;
mBitmap.LoadFromStream(mStream);
Image4.Picture.Assign(mBitmap);
end;

Cognos Checkbox + Oracle Stored Procedure

Here is what I am trying to do
I have a report that looks like this
id name address
id name address
What I would like to do is add a checkbox at the end of each line like so
id name address checkbox
id name address checkbox
What I would like to do is when the user hits the checkbox and hits submit, it will put the id_number into an oracle stored procedure like so
examplestoredprocedure(id_number||,||id_number)
or something similar.
has anyone done anything like this? We have links the user hits and it hits a stored procedure but not with multi values.
Any help would be appreciated
You can do these:
define a procedure on db
//package body on oracle in my case
CREATE OR REPLACE PACKAGE BODY my_package AS
procedure my_procedure ( username in varchar2 ,p_return out sys_refcursor
) as
v_Return varchar2(4000) := null;
begin
--do something
v_Return:=username;
open p_return FOR
SELECT CAST(v_Return AS varchar2(4000))from dual;
end my_procedure;
END my_package;
/
create procedure on your cognos framework
// you should use macros like this :# prompt('p_UserName','string' ,'temp')#
create a cognos report and use javascript//in prompt page
//define checkbox in list with js like this : <input type="CHECKBOX" id="you can define your data item" name="chck1" ></input>
//you should set your values to parameters and then click button like this:
<a title = 'okey'; onClick="myFunction('chck1')">your button</a>
//define function
function myFunction(chkboxName)
{
var checkboxes = document.getElementsByName(chkboxName);
for (var i=0; i<checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
//alert( ' index '+i +' - ' +checkboxes[i].id );
var form = getFormWarpRequest();
var textBox = form._textEditBoxmyeditboxname;//this is important editbox name is : myeditboxname //this is standart : form._textEditBox
{
textBox.value = textBox.value+checkboxes[i].id+',';//this is uses for setting parameter value , you can set your parameter
}
}
}
promptButtonFinish(); //this uses like finish prompt
}
and finally you can set your report page put there your procedure output(:B1)
//put this data item to your page
[Business Layer].[yourdataitem].[:B1]
this is working for me , I hope it solves your problem

Inno Setup: How to create password wizard page only if component "X" selected

Can anyone help me to protect a selection group or component.
For examples
If ('Readme.txt').selected or ('compact').selected = True then
begin "Password wizard page";
else
result := true;
end;
Something like that to this working script :P
function CheckPassword(Password: String): Boolean;
begin
result := false;
if (Password='component') or (Password='type') then
result := true;
end;
I'm not sure I completely understood your question, but maybe this helps. Here are a few functions you only need to add to the [code] section of the Components.iss sample, and one of the components ("help") can only be installed when the user enters the correct password.
Since you need the password later in the installation, and not always, you can not use the standard setup password page. You will instead create your own page and insert it after the components selection page:
[Code]
var
PasswordPage: TInputQueryWizardPage;
procedure InitializeWizard();
begin
PasswordPage := CreateInputQueryPage(wpSelectComponents,
'Your caption goes here',
'Your description goes here',
'Your subcaption goes here');
PasswordPage.Add(SetupMessage(msgPasswordEditLabel), True);
end;
Note that this uses the translated password caption, you may need to make the other three strings translatable as well.
Next you will need to hide that page if the user has not selected the component for installation:
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if PageID = PasswordPage.ID then begin
// show password page only if help file is selected for installation
Result := not IsComponentSelected('help');
end;
end;
Finally you need to check the password, and prevent the user from going to the next page if the password is wrong:
function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if CurPageID = PasswordPage.ID then begin
// stay on this page if password is wrong
if PasswordPage.Edits[0].Text <> 'my-secret-password' then begin
MsgBox(SetupMessage(msgIncorrectPassword), mbError, MB_OK);
Result := False;
end;
end;
end;