Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NullVariant: OleVariant absolute 0 (D6 ?)

170 views
Skip to first unread message

Rolf Frei

unread,
Aug 23, 2001, 7:30:51 AM8/23/01
to
How must this definition be declared in D6?

var
NullVariant: OleVariant absolute 0;

I get an error "Varable name expected"

Bye Rolf
--
Eicom GmbH
Electronic Internet Commerce
5712 Beinwil am See
Switzerland
www.eicom.ch


Lubos Medovarsky

unread,
Aug 23, 2001, 8:20:33 AM8/23/01
to

'Absolute' is not supported in D6.

I tried this:

--------------------------
program Project1;

uses
SysUtils, Variants;

var
NullVariant: OleVariant = Unassigned; << error assigning value
begin
end.
--------------------------

Compiler complains:

[Error] Project1.dpr(9): This type cannot be initialized

I cannot be done this way because Unassigned is actually function
(it calls VarUtils.VariantClear from oleaut dll)
returning initialized Variant type.

--------------------------
<help>

This type cannot be initialized

File types (including type Text), and the type Variant cannot be
initialized, that is, you cannot declare typed constants or initialized
variables of these types.

program Produce;

var
V: Variant = 0;

begin
end.

The example tries to declare an initialized variable of type Variant,
which illegal.

program Solve;

var
V: Variant;

begin
V := 0;
end.

The solution is to initialize a normal variable with an assignment
statement.
</help>
--------------------------

Eg., help says do NullVariant := Unassigned; at runtime.


Regards,

--
Lubos Medovarsky

Switching and Routing Division
ALCATEL Slovakia, a.s.

ShaneB

unread,
Aug 23, 2001, 1:12:11 PM8/23/01
to
I'm not an expert since I rarely used variants, but can't you just do this?

uses Variants;

var
NullVariant: OleVariant;
...

NullVariant := Null;

ShaneB


Rolf Frei

unread,
Aug 23, 2001, 1:38:40 PM8/23/01
to
ShaneB,

I have already tried this but it seems not to be the same. The only version
I can get to work the Call to the interface is this:

HrExecCommand(IDM_FONTNAME, {NullVariant} OleVariant(nil^), vo, False,
False);

The problem is that I can't define this OleVariant(nil^) to a global var or
constant. This was done by this "absolute" definition in D5 but it seems not
anymore to work in D6.

Bye Rolf

"ShaneB" <stor...@bigfoot.com> schrieb im Newsbeitrag
news:3b853909_2@dnews...

Peter Below (TeamB)

unread,
Aug 23, 2001, 3:11:10 PM8/23/01
to
In article <3b84e8b8_1@dnews>, Rolf Frei wrote:
> How must this definition be declared in D6?
>
> var
> NullVariant: OleVariant absolute 0;

I have no idea what this is supposed to represent, it certainly (if it
compiled) would not be a variant of type VarNull. It would be a variant
variable at address 0 and using it would result in an AV.

In the Variants unit there is a

function Null: Variant;

This replaces the old NULL variant constant. To test a variant for the
NULL value use the VarIsNull function, do not compare to a NULL
variant.


Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Note: I'm unable to visit the newsgroups every day at the moment,
so be patient if you don't get a reply immediately.

Ray Lischner

unread,
Aug 23, 2001, 2:31:13 PM8/23/01
to
Rolf Frei wrote:

> HrExecCommand(IDM_FONTNAME, {NullVariant} OleVariant(nil^), vo,
> False,
> False);

That makes no sense. What is HrExecCommand? It looks like it takes a
VAR OleVariant parameter, and then uses its address, which you are
passing as nil. OleVariant(nil^) is NOT a Null Variant value.
--
Ray Lischner, author of Delphi in a Nutshell
http://www.tempest-sw.com

Rolf Frei

unread,
Aug 24, 2001, 7:09:54 AM8/24/01
to
> That makes no sense. What is HrExecCommand? It looks like it takes a
> VAR OleVariant parameter, and then uses its address, which you are
> passing as nil. OleVariant(nil^) is NOT a Null Variant value.

Yes I know, but that is exactly the problem. The routine must get a C++ null
value (not a null variant) to work correctly. Only so I can get the actual
values back from the routine. In D5 this was possible by defining this
absolute 0 variable. This all is used for the DHTML /MSHTML control.

This is the complete HrExecCommand routine:

function TfrmMain.HrExecCommand(cmdID: cardinal; const pVarIn: OleVariant;
var pVarOut: OleVariant; bPromptUser: boolean;
bTriEditCmdGroup: boolean): HResult;;
var
dwCmdOpt: DWORD;
begin
result := S_OK;
if (not Assigned(CommandTarget)) then
Exit;

if (bPromptUser) then
dwCmdOpt := MSOCMDEXECOPT_PROMPTUSER
else
dwCmdOpt := MSOCMDEXECOPT_DONTPROMPTUSER;

if (bTriEditCmdGroup) then
result := CommandTarget.Exec(@GUID_TriEditCommandGroup, ucmdID,
dwCmdOpt, pVarIn, pVarOut)
else
result := CommandTarget.Exec(@CMDSETID_Forms3, ucmdID, dwCmdOpt, pVarIn,
pVarOut);
end;

Hopefully you can help me.

Bye Rolf

Rolf Frei

unread,
Aug 24, 2001, 7:12:18 AM8/24/01
to
> I have no idea what this is supposed to represent, it certainly (if it
> compiled) would not be a variant of type VarNull. It would be a variant
> variable at address 0 and using it would result in an AV.
>
> In the Variants unit there is a
>
> function Null: Variant;
>
> This replaces the old NULL variant constant. To test a variant for the
> NULL value use the VarIsNull function, do not compare to a NULL
> variant.

It must be a OleVariant compatible nil pointer (null in C++) and not a null
variant. Please see also my answer to Ray Lischner.

Bye Rolf.


ShaneB

unread,
Aug 24, 2001, 12:12:40 PM8/24/01
to
> It must be a OleVariant compatible nil pointer (null in C++) and not a
null
> variant. Please see also my answer to Ray Lischner.


That makes no sense :)

If it want's a nil pointer, then send it nil. If it wants a null variant,
send it an OleVariant set to Variants.Null. If it wants a null (as in C++),
then send it 0. You're definately doing something wrong...and I'd love to
figure out what....but without more code or some way to try the function (or
a similar one) on my machine, I cannot really say more.

The absolute 0 thing....well, in your older version, I'd say you just got
lucky to get it working at all..

I could be way off but this *seems* like an easy problem to figure out...

ShaneB


Rudy Velthuis (TeamB)

unread,
Aug 24, 2001, 12:04:18 PM8/24/01
to
In article <3b84e8b8_1@dnews>, Rolf Frei says...

> How must this definition be declared in D6?
>
> var
> NullVariant: OleVariant absolute 0;
>
> I get an error "Varable name expected"

Indeed. It seems that absolute addressing is not accepted anymore (which
is a good thing).

Why don't you simply use Null?

--
Rudy Velthuis (TeamB)

Rolf Frei

unread,
Aug 24, 2001, 12:47:06 PM8/24/01
to
Please see the other messages in this thread. Variant Null isn't the same as
C++ Null or nil. As this is a var OleVariant paramter I can't pass nil to
it.

Bye Rolf


"Rudy Velthuis (TeamB)" <rvel...@gmx.de> schrieb im Newsbeitrag
news:MPG.15f099709...@newsgroups.borland.com...

Rolf Frei

unread,
Aug 24, 2001, 12:37:54 PM8/24/01
to
ShaneB,

You can download the OpenSource DHTML-Delphi Control (it's TFrame) from this
side:

http://groups.yahoo.com/group/delphi-dhtmledit/files/

You need to login to get access. Try to compile this project and then run
it. Now try to select an other fontname or fontsize. This doesn't work, its
jumps just back to the old value. This is caused by this special parameter.

I'm very interested what you find out.

Regards
Rolf

"ShaneB" <stor...@bigfoot.com> schrieb im Newsbeitrag

news:3b867c94_2@dnews...

Ray Lischner

unread,
Aug 24, 2001, 12:09:16 PM8/24/01
to
Rolf Frei wrote:

> Yes I know, but that is exactly the problem. The routine must get a
> C++ null value (not a null variant) to work correctly.

Then declare it as a pointer, and pass nil (instead of nil^). If, for
some reason, you must pass a const Variant, using nil^ is the "correct"
way to do so.

Rolf Frei

unread,
Aug 24, 2001, 1:10:28 PM8/24/01
to
Ups, it is a const OleVariant parameter and not a var. This is the complete
Interface of problem (the Exec functiin):

{$EXTERNALSYM IOleCommandTarget}
IOleCommandTarget = interface(IUnknown)
['{b722bccb-4e68-101b-a2bc-00aa00404770}']
function QueryStatus(CmdGroup: PGUID; cCmds: Cardinal;
prgCmds: POleCmd; CmdText: POleCmdText): HResult; stdcall;
function Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
const vaIn: OleVariant; var vaOut: OleVariant): HResult; stdcall;
end;

Bye Rolf.

"Rolf Frei" <ro...@eicom.ch> schrieb im Newsbeitrag news:3b868453_2@dnews...

Ray Lischner

unread,
Aug 24, 2001, 3:29:44 PM8/24/01
to
Rolf Frei wrote:

> function Exec(CmdGroup: PGUID; nCmdID, nCmdexecopt: DWORD;
> const vaIn: OleVariant; var vaOut: OleVariant): HResult;

Why do you need to pass a value for valn such that when Exec takes the
address of valn, Exec sees nil? Either the class that implements
IOleCommandTarget is broken, or your understanding of that class is
wrong, or my understanding of the problem is wrong.

Something is rotten in the state of Denmark.

Rudy Velthuis (TeamB)

unread,
Aug 24, 2001, 3:58:12 PM8/24/01
to
In article <3b868453_2@dnews>, Rolf Frei says...

> Please see the other messages in this thread. Variant Null isn't the same as
> C++ Null or nil. As this is a var OleVariant paramter I can't pass nil to
> it.

What is the declaration of the function?
--
Rudy Velthuis (TeamB)

ShaneB

unread,
Aug 24, 2001, 4:36:11 PM8/24/01
to
Well, I played with it a little bit....

"Now try to select another fontname or fontsize. This doesn't work, its


jumps just back to the old value. This is caused by this special parameter."

That's not it...the problem is that you're recalling the HrExecCommand
immediately after (in the DHTMLEditDisplayChanged event) with a null
variant. What did you intend to do with the lines below?

Here's where it's recalling HrExecCommand:
FontNameStatus := GetCommandStatus(IDM_FONTNAME, False);
FontSizeStatus := GetCommandStatus(IDM_FONTSIZE, False);
if ((FontNameStatus and OleCmdf_Enabled) <> 0) then begin
HrExecCommand(IDM_FONTNAME, NullVariant, vo, False, False);
if (VarType(vo) = VarOleStr) then
cmbFontName.ItemIndex := cmbFontName.Items.IndexOf(Vo);
end;
VarClear(vo);
if ((FontSizeStatus and OleCmdf_Enabled) <> 0) then begin
HrExecCommand(IDM_FONTSIZE, NullVariant, vo, False, False);
if (VarType(vo) = VarInteger) then
cmbFontSize.ItemIndex := cmbFontSize.Items.IndexOf(vo);
end;

Comment out both of the HrExecCommand lines above and all works as expected.

HTH,
ShaneB

ShaneB

unread,
Aug 24, 2001, 5:47:45 PM8/24/01
to
Here's a simpler illustration of using the control and just changing font
names/sizes:

unit main;

interface

uses
Windows, Messages, Classes, Controls, Forms, OleCtrls, DHTMLEDLib_TLB,
ComCtrls,
Menus, ExtCtrls, ActiveX, mshtml_tlb, IEConst, ComObj, ToolWin, Variants,
StdCtrls;

type
TGetInputArg = procedure(Sender: TObject; var pVarIn: OleVariant; var
FuncResult: boolean) of object;
TClearInputArg = procedure(Sender: TObject; var pVarIn: OleVariant) of
object;
TfrmMain = class(TForm)
Panel1: TPanel;
StatusBar1: TStatusBar;
PageControl1: TPageControl;
tabEdit: TTabSheet;
DHTMLEdit: TDHTMLEdit;
CoolBar: TCoolBar;
tlb_Format: TToolBar;
ToolButton2: TToolButton;
cmbFontName: TComboBox;
ToolButton4: TToolButton;
cmbFontSize: TComboBox;
procedure cmbFontNameChange(Sender: TObject);
procedure cmbFontSizeChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;

implementation

{$R *.DFM}


procedure TfrmMain.FormCreate(Sender: TObject);
begin
cmbFontName.Items.Assign(Screen.Fonts);
cmbFontName.OnChange := cmbFontNameChange;
cmbFontSize.OnChange := cmbFontSizeChange;
end;

procedure TfrmMain.cmbFontNameChange(Sender: TObject);
var
vi: OleVariant;
dwCmdOpt: DWORD;
begin
vi := cmbFontName.Text;
dwCmdOpt := MSOCMDEXECOPT_DONTPROMPTUSER;
DHTMLEdit.ExecCommand (DECMD_SETFONTNAME, dwCmdOpt, vi);
end;

procedure TfrmMain.cmbFontSizeChange(Sender: TObject);
var
vi: OleVariant;
dwCmdOpt: DWORD;
begin
vi := cmbFontSize.ItemIndex + 1;
dwCmdOpt := MSOCMDEXECOPT_DONTPROMPTUSER;
DHTMLEdit.ExecCommand (DECMD_SETFONTSIZE, dwCmdOpt, vi);
end;

initialization
OleInitialize(nil);

finalization
OleUninitialize;
end.


HTH,
ShaneB


Anders Melander

unread,
Aug 24, 2001, 6:34:59 PM8/24/01
to
Ray Lischner <donts...@spam.you> wrote:

>Something is rotten in the state of Denmark.

Yeah, our current government, but what's that got to do with it?

Rolf Frei

unread,
Aug 24, 2001, 6:57:30 PM8/24/01
to
> That's not it...the problem is that you're recalling the HrExecCommand
> immediately after (in the DHTMLEditDisplayChanged event) with a null
> variant. What did you intend to do with the lines below?

If the parameter is a NullVariant it returns the actual fontname of the
selection. If it isn't NullVariant it sets the fontname of the selection.
This routine is called by the DHTML-edit itself (OnDisplayChanged) and does
return the actual fontname and other settings, while we navigate in the
edit. So the buttons and comboboxes are right update with the actual
settings of the cursor position. When you pass OleVariant(nil^) to this
routine you can see that this works correctly. As soon I use any other value
like the variant Null, it fails to work, as the call thinks I want to set a
new FontName instead to get the actual fontname back.

This is from the DHTML-SDK under IDM_FONTNAME Command ID:
pvaOut: pvaOutVARIANT of type VT_BSTR that receives the font name for the
current selection. If the current selection uses more than one font, pvaOut
will return a VARIANT of type VT_NULL. Set pvaIn to NULL to retrieve
information to pvaOut.

Regards
Rolf


Rolf Frei

unread,
Aug 25, 2001, 8:00:22 AM8/25/01
to
> That's not it...the problem is that you're recalling the HrExecCommand
> immediately after (in the DHTMLEditDisplayChanged event) with a null
> variant. What did you intend to do with the lines below?

If the parameter is a NullVariant it returns the actual fontname of the

Peter Below (TeamB)

unread,
Aug 25, 2001, 9:07:45 AM8/25/01
to
In article <3b8635de_1@dnews>, Rolf Frei wrote:
> It must be a OleVariant compatible nil pointer (null in C++) and not a null
> variant. Please see also my answer to Ray Lischner.
>

In that case the function has been translated poorly, instead of using a
Const parameter it should have declared the parameter as a PVariant.

Pass POleVariant(nil)^

were Type POleVariant = ^OleVariant. May be predeclared already somewhere.

Rolf Frei

unread,
Aug 25, 2001, 12:54:45 PM8/25/01
to
The declaration was done by the ActiveX Typlibrary importer.

Bye
Rolf

"Peter Below (TeamB)" <10011...@compuXXserve.com> schrieb im Newsbeitrag
news:VA.0000778...@antispam.compuserve.com...

ShaneB

unread,
Aug 25, 2001, 3:24:33 PM8/25/01
to
> This is from the DHTML-SDK under IDM_FONTNAME Command ID:
> pvaOut: pvaOutVARIANT of type VT_BSTR that receives the font name for the
> current selection. If the current selection uses more than one font,
pvaOut
> will return a VARIANT of type VT_NULL. Set pvaIn to NULL to retrieve
> information to pvaOut.

Ah, I see....I shoulda figured that out :)

anyway, here's the same code that works and updates the fonts correctly:
unit main;

interface

uses
Windows, SysUtils, Messages, Classes, Controls, Forms, OleCtrls,
DHTMLEDLib_TLB, ComCtrls,
Menus, Dialogs, ExtCtrls, ActiveX, mshtml_tlb, IEConst, ComObj, ToolWin,
Variants, StdCtrls;

type


TfrmMain = class(TForm)
Panel1: TPanel;
StatusBar1: TStatusBar;
PageControl1: TPageControl;
tabEdit: TTabSheet;
DHTMLEdit: TDHTMLEdit;
CoolBar: TCoolBar;
tlb_Format: TToolBar;
ToolButton2: TToolButton;
cmbFontName: TComboBox;
ToolButton4: TToolButton;
cmbFontSize: TComboBox;
procedure cmbFontNameChange(Sender: TObject);
procedure cmbFontSizeChange(Sender: TObject);
procedure FormCreate(Sender: TObject);

procedure DHTMLEditDisplayChanged(Sender: TObject);

var
frmMain: TfrmMain;

implementation
{$R *.DFM}

procedure TfrmMain.DHTMLEditDisplayChanged(Sender: TObject);
var
v: OleVariant;
begin
{ Update the comboboxes }
v := DHTMLEdit.ExecCommand(DECMD_GETFONTNAME,
MSOCMDEXECOPT_DONTPROMPTUSER);
if (VarType(v) = VarOleStr) then
cmbFontName.ItemIndex := cmbFontName.Items.IndexOf(v);

v := Null; { just to be sure }
v := DHTMLEdit.ExecCommand(DECMD_GETFONTSIZE,
MSOCMDEXECOPT_DONTPROMPTUSER);
if (VarType(v) = VarOleStr) then
cmbFontSize.ItemIndex := cmbFontSize.Items.IndexOf(v);
end;

initialization
OleInitialize(nil);

finalization
OleUninitialize;
end.


ShaneB


0 new messages