Solved

String type to word type

Posted on 2004-08-23
19
242 Views
Last Modified: 2011-09-20
 I have an activeX from Microsoft which has some functions that include a Word type variable. That variable is actually a string (like 'id=myID'). On msdn they pass that variable to the function like "id=myID", and all the info they give is that this is an OleChar variable. Thay can do that because C has almost no type checking, but Delphi has strong type checking...
  Now, I need to know how can I pass a string as a Word to this function. There must be a way to do it, maybe with pointers...
0
Comment
Question by:Bindza
  • 8
  • 4
  • 2
  • +3
19 Comments
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
try to use PChar or PAnsichar in delphi, instead of string -> there are conversion-functions

-> just a guess -> no activeX-experience

meikl ;-)
0
 

Author Comment

by:Bindza
Comment Utility
It's got nothing to with ActiveX in particular, I just said that so people would know what's it all about.

I forgot to add, I tried this:

var
 w: word;
 s: string;
 p: ^word;
begin
s := 'myid=SomeId';
p := @s;
w := p^;
TheMSFunction(w);
[...]

But the function returns "?" instead of "myid=SomeId".
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
are you sure that not a DWord is used?

try this

TheMSFunction(integer(PChar('myid=SomeId'));


0
 
LVL 17

Expert Comment

by:Wim ten Brink
Comment Utility
I just think there's a flaw in the type library you're using. Which control are we talking about here?

Or perhaps it's an OVERLOADED method...
0
 
LVL 13

Expert Comment

by:BlackTigerX
Comment Utility
can you show the code you have that shows how they pass the "id=myID" to the function?

also, from the Delphi IDE, when you are in the parameters part of that function and you hit Ctrl+Shift+Space Bar, what does the parameter type say?
0
 

Author Comment

by:Bindza
Comment Utility
It's WebBrowser that is DHTMLEd, the function (IMarkupServices.CreateElement) as MS presents it is:

HRESULT CreateElement(ELEMENT_TAG_ID tagID,
    OLECHAR* pchAttributes, // here - delphi sees it as Word
    IHTMLElement** ppElement
);
Parameters

tagID
[in] Value of type ELEMENT_TAG_ID that specifies the type of tag to create.
pchAttributes
[in] Pointer to a variable of type OLECHAR that specifies the attributes of the element.
ppElement
[out] Address of a pointer to an IHTMLElement interface that returns the newly created element.

And this is how they use it:

IMarkupServices::CreateElement ( TAGID_B, "id=anID", & pElement ) will create a new b element with the attribute IHTMLElement::id set to "anID".

This is how I tried to use it:

uses MSHTML_TLB;

procedure TForm1.Button1Click(Sender: TObject);
var
 i: IMarkupServices;
 e: IHTMLElement;
 w: word;
 s: string;
 p: ^word;
begin
//w := 0; for no attributes
s := 'src="C:\tmp\logomain.jpg"';
p := @s;
w := p^;
KSEditx1.DOM.QueryInterface(IID_IMarkupServices, i);
if i <> nil then
 begin
  i.createElement(TAGID_IMG, w, e);
  showmessage(e.outerhtml);// shows "<IMG ?>" instead of <IMG src="C:\tmp\logomain.jpg">
 end;
end;
0
 

Author Comment

by:Bindza
Comment Utility
in WebBrowser that would be:

[...]
(WebBrowser1.Document as IHTMLDocument2).QueryInterface(IID_IMarkupServices, i);
if i <> nil then
 begin
  i.createElement(TAGID_IMG, w, e);
  showmessage(e.outerhtml);// shows "<IMG ?>" instead of <IMG src="C:\tmp\logomain.jpg">
 end;
end
0
 
LVL 13

Expert Comment

by:BlackTigerX
Comment Utility
have you tried typecasting to Word:

procedure TForm1.Button1Click(Sender: TObject);
var
 i: IMarkupServices;
 e: IHTMLElement;
 w: word;
 s: string;
 p: ^word;
begin
//w := 0; for no attributes
s := 'src="C:\tmp\logomain.jpg"';
//p := @s; //don't need this
//w := p^; //don't need this
KSEditx1.DOM.QueryInterface(IID_IMarkupServices, i);
if i <> nil then
 begin
  i.createElement(TAGID_IMG, Word(PChar(s)), e); //typecast here
  showmessage(e.outerhtml);// shows "<IMG ?>" instead of <IMG src="C:\tmp\logomain.jpg">
 end;
end;
0
 

Author Comment

by:Bindza
Comment Utility
I think I have and it said "Invalid typecast"...
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 33

Expert Comment

by:Slick812
Comment Utility
Hello  Bindza, I'm sorry I do not have time to actually test this code before I post it, but I think I would try and just Typecaste a PWChar to a PWORD


procedure TForm1.Button1Click(Sender: TObject);
var
 i: IMarkupServices;
 e: IHTMLElement;
 s: string;
 pWCha1: PWChar;
begin
s := 'src="C:\tmp\logomain.jpg"';
pWCha1 := StringToOleStr(s);
KSEditx1.DOM.QueryInterface(IID_IMarkupServices, i);
if i <> nil then
 begin
  i.createElement(TAGID_IMG, PWORD(pWCha1)^, e);
  showmessage(e.outerhtml);
 end;
end;


but I am conpleatly dumbfounded by the Delphi code heads making a PWChar to a Word for that parameter?
0
 
LVL 12

Expert Comment

by:Lee_Nover
Comment Utility
agreed with slick :-)
delphi should still import it as a pointer of some sort
if it doesn't work manually change the interface so that the param becomes a PWideChar or maybe 'var WideString'
0
 

Author Comment

by:Bindza
Comment Utility
I'll try it.
0
 

Author Comment

by:Bindza
Comment Utility
Thanks Slick, I tried it and it works perfectly :)
Now, if you could tell me how to convert a string like "TAGID_BUTTON" to a word like "TAGID_BUTTON" you'll get more points. I'm not really sure that this is a word, it may be an integer, in MSHTML_TLB it's defined like this:

// Constants for enum _ELEMENT_TAG_ID
type
  _ELEMENT_TAG_ID = TOleEnum;
const
  TAGID_NULL = $00000000;
  TAGID_UNKNOWN = $00000001;
  TAGID_A = $00000002;
  [...]
  TAGID_BUTTON = $00000011;

and the commands are defined like this (they are integers, obviously):

  IDM_UNKNOWN               =  0;
  IDM_ALIGNBOTTOM           =  1;
  IDM_ALIGNHORIZONTALCENTERS=  2;
  IDM_ALIGNLEFT             =  3;
  [...]

I need this so the user can specify which element he/she wants to insert, and also with the mshtml IDM_SOMETHING commands (there are so many of them that trying them all, by modifying the source and recompiling, would take forever, and I don't want a 200 line "case" or "if" statement).
0
 

Author Comment

by:Bindza
Comment Utility
So, What do you think, Slick?
0
 
LVL 12

Expert Comment

by:Lee_Nover
Comment Utility
no conversion is needed .. those consts already are integers
in delphi $0001 is a number in HEX format (in VB it's a string variable)
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
???
these are all Number (Integer) constant values, and You seem to want some sore of conversion like

function convertS(aName: String): Integer;
begin
Result := someMagicAPI_Fuction(PChar(aName));
end;

but I do not know of anything like that

SO

GUESS WHAT

it seems to me the only way to get this type of thing is with an if test or case test for ALL the "String Names" you want to have for your users to use, , and then convert that string name to the constant value for that element type

I think this is standard procedure for having user "words" for programming code types
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
Oh the only alternative I can thing of is to use the string for the numeric value

EName := '$11';

function convertS(aName: String): Integer;
begin
Result := StrToInt(aName);
end;

but I do not think this would be very popular with your users
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 375 total points
Comment Utility
you may could use a ComboBox with element Names like "Bold" , "Button" , "Link" or  "Image" and then set the Constant by the index of the Combo Box
0
 

Author Comment

by:Bindza
Comment Utility
Very good idea, thanks. I wonder why didn't I think of that...
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video discusses moving either the default database or any database to a new volume.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now