How to fill "waveInGetDevCaps" function parameters in Delphi? - windows

I'm using the Window's API, in particular the 'WaveIn' functions. I want to know the format that my laptop's input audio device supports.
Therefore, I used the function "waveInGetDevCaps." This function call , once called, fills in a WAVEINCAPS structure with the information about the audio device.
This is my code so far:
procedure TForm1.Button4Click(Sender: TObject);
var
wc : WAVEINCAPS; // structure to be filled with audio device info
begin
waveInGetDevCaps(WAVE_MAPPER, &wc, sizeof(WAVEINCAPS));
Showmessage (wc.dwFormats);
end;
However I keep getting an error:
"E2010 Incompatible types: 'PWaveInCapsA' and 'tagWAVEINCAPSA2"
I would appreciate any help please.
Information on "waveInGetDevCaps" and "WAVEINCAPS" can be found:
https://msdn.microsoft.com/en-us/library/dd743841%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/dd743839%28v=vs.85%29.aspx

You are using the wrong operator to take the address. You use & in C and C++. In Delphi the operator is #. This operator is documented here: http://docwiki.embarcadero.com/RADStudio/en/Expressions_(Delphi)#The_.40_Operator
In Delphi, & is used to escape keywords. It has no effect here, because wc is not a keyword, and is essentially ignored, treated as whitespace.
Replace & with # and your code will compile. Don't forget to check the return value of the function call for errors, as described in the function documentation.
The Delphi header translations introduce Pascal-case type names so instead of the WAVEINCAPS type it would be idiomatic to use the TWaveInCaps type.

Related

DialogFlow CX inline system functions not working in text fulfillment

I would like to generate dynamic text without the need to create webhooks whenever possible. I understand that the only way to create dynamic text is by either creating different routes depending on parameters or by using inline system functions like $sys.func.ADD(1, 2) within text fulfillments.
But inline system functions like $sys.func.ADD(1, 2) do not work for me if used in text fulfillments. System functions just don't get executed for me. I.e. instead of uttering "3" my bot just utters "$sys.func.ADD(1, 2)" as a result of a test fulfillemnt. What am I doing wrong here? Does anybody have an example for using inline system functions in text fulfillment?
Thanks!
To resolve this issue, you need to check the result of system functions in order to identify the error that occurred.
For the system function $sys.func.ADD, when using it as a text response in your fulfillment, you need to convert it to type STRING to be embedded in text since the output of this system function returns a type DOUBLE.
You can convert the output of the $sys.func.ADD function to STRING by creating a nested function in your text response and utilizing the $sys.func.TO_TEXT which converts a value of other types to string.
Here’s an example for reference:

Convert AnsiString to UnicodeString in Lazarus with FreePascal

I found similar topics here but none of them had the solution to my question, so I am asking it in a new thread.
Couple of days ago, I changed the format the preferences of an application I am developing is saved, from INI to JSON.
I use the jsonConf unit for this.
A sample of the code I use to save a key-value pair in the file would be like below.
Procedure TMyClass.SaveSettings();
var
c: TJSONConfig;
begin
c:= TJSONConfig.Create(nil);
try
c.Filename:= m_settingsFilePath;
c.SetValue('/Systems/CustomName', m_customName);
finally
c.Free;
end;
end;
In my code, m_customName is an AnsiString type variable. TJSONConfig.SetValue procedure requires the key and value both to be of UnicodeString type. The application compiles fine, but I get warnings such
Warning: Implicit strung type conversion from "AnsiString" to "UnicodeString".
Some messages warn saying there is a potential data loss.
Of course I can go and change everything to UnicodeString type but this is too risky. I have't seen any issues so far by ignoring these warnings, but they show up all the time and it might cause issues on a different PC.
How do I fix this?
To avoid the warning do an explicit conversion because this way you tell the compiler that you know what you are doing (I hope...). In case of c.SetValue the expected type is a Unicodestring (UTF16), m_customname should be declared as a string unless there is good reason to do differently (see below), otherwise you may trigger unwanted internal conversions.
A string in Lazarus is UTF8-encoded, by default. Therefore, you can use the function UTF8Decode() for the conversion from UTF8 to Unicode, or UTF8ToUTF16() (unit LazUtf8).
var
c: TJSONConfig;
m_customName: String;
...
c.SetValue('/Systems/CustomName', UTF8Decode(m_customName));
You say above that the key-value pairs are in a file. Then the conversion depends on the encoding of the file. Normally I open the file in a good text editor and find the encoding somewhere - NotePad++, for example, displays the name of the encoding in the right corner of the statusbar. Suppose the encoding is that of codepage 1252 (Latin-1). These are ansistrings, therefore, you can declare the strings read from the file as ansistring. Because UTF8 strings are so common in Lazarus there is no direct conversion from ansistring to Unicode, and you must convert to UTF8 first. In the unit lconvencoding you find many conversion routines between various encodings. Select CP1252toUTF8() to go to UTF8, and then apply UTF8Decode() to finally get Unicode.
var
c: TJSONConfig;
m_customName: ansistring;
...
c.SetValue('/Systems/CustomName', UTF8Decode(CP1252ToUTF8(m_customName)));
The FreePascal compiler 3.0 can handle many of these conversions automatically using strings with predefined encodings. But I think explicit conversions are very clear to see what is happening. And fpc3.0 still emits the warnings which you want to avoid...

how to internationalize a delphi application [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Translate application
What is the best way to internationalize my application written in delphi xe2 ?
I've seen the stringtable resource but I'm worried because I've got the feeling that the implementation could be time consuming and laborious.
Are there other equally valid methods to do this?
Maybe not the best tool for translations, but I'm using GNU Gettext for many years.
The process is quite simple:
You run dxgettext to extract strings
You translate or give for translation the files
I personally love poEdit tool to translate and manage translation repository
Optional : You merge your translation files into the final EXE
OR you put the translation files in subdirectories and that's it !
http://dxgettext.po.dk/
Update:
1/ GNU Gettext is included in JCL/JVCL library, you just need to activate this option at startup.
2/ Gnu Gettext can translate everything in the library, as VCL, JCL/JVCL also ! It's not just limited to your code !
One option is to use the Integrated Translation Environment in Delphi:
http://docwiki.embarcadero.com/RADStudio/XE3/en/Localizing_Applications_by_Using_Translation_Manager_Overview
Here you can find two articles about this theme:
Multilingua application with GNU gettext
Multilingua application with standard method (IDE)
You can find other methods and commencial components (i have used TsiLang components -excellent library-)
A Greeting.
I don't know is this the best way of internationalize an application, but for me it worked. It's a kind of home made.
I created an xml file, which is the dictionary containing the translations, but you can use any other format, from json, to xls (maybe this is the best). Than implemented a class which read the translations from this file, and a way to register procedures in case of the language is changed runtime, which is I think a good feature.
TDictionary = class
private
fOnChanged: TSignal;
fLanguage: String;
procedure setLanguage( const Value: String );
public
procedure loadFromFile( filename: string );
function getTranslation( id: string; lang: string = '' ): string;
property language: String read fLanguage write setLanguage;
property onChanged: TSignal read fonChanged;
end;
...
function TDictionary.getTranslation( id: string; lang: string = '' ): string;
begin
if lang = '' then
lang := Language; // use the default lang.
// read the translation from the file.
end;
procedure TDictionary.setLanguage( const Value: String );
begin
fLanguage := Value;
onChanged.Execute;
end;
TSignal is a class which register methods, and if you call Execute executes all the registered methods, Maybe in xe2 you have something built in for this, in delphi7 I had to create this class myself, but it's fun to implement.
in a form's createForm:
procedure TMyClass.doTranslate( dictionary: TObject );
begin
with dictionary as TDictionary do
begin
caption := dictionary.getTranslation( 'myclass.caption' );
button.caption := dictionary.getTranslation( 'some id' );
end;
// or you can go through Controls array, and automate the assignment.
end;
procedure TMyClass.FormCreate(Sender: TObject);
begin
Dictionary.onChanged.register( doTranslate );
doTranslate( dictionary );
end;
procedure TMyClass.FormDestroy(Sender: TObject);
begin
Dictionary.onChanged.deregister( doTranslate );
end;
As you can see, this is not a working example what you can copy and paste, I just wanted to show you the idea behind. if something is not clear, comment it, and I can extend my answer.
Some notes:
I think it's important to have the translations in utf8 format.
using xls makes the localizers live easier, and your too, if they ruin your xml file (If the translator is not prof., It can happen that you get back your xml file in microsoft word format)
you can put your dictionary file into resource, and load from there.
Pros
This way you can change the language runtime
if you need another language, you just need to edit the dictionary file.
Cons
If you have many forms, it's a nightmare to connect all the labels, buttons, etc, but you can automate it in smart ways.
It slows down your app a little, but not much, if changing your app language is not happening so often.
There is a product called sisulizer, it works after you have build the executable fies I think. Haven't tried it but I've read a lot about it.
Have a look at this

Excel UDF returns a huge number

Excel AddIn using Excel DNA, VS2008, C#,
MyUDF(param1, parm2)
when I type in "=MyUDF" and hit enter, Excel displays a huge number like 970063926
and my c# code for MyUDF is not run
Anyone know what is this huge number?
thanks
This is just a bit of weird behaviour of Excel. The number being returned is an internal identifier for the UDF function, and by entering the function name without any brackets, you're causing it to be treated like a named range not a function. If you want to call the function with no arguments, use:
=MyUDF()
...if you type =MyUDF then you're asking Excel to dereference the function name, in the same way that it would dereference =A1 to the value in cell A1 or =MyNamedRange to whatever that named range referred to.
I don't think there's any practical use for the behaviour you've observed, but it certainly isn't going anywhere near your code to get this value that is being returned, so don't worry you haven't done anything wrong!
Is there any way to avoid this behavior?
If no parameter is specified, I would like the =MyUDF to return error instead a number.

How to programmatically trigger Flip 3D on Windows?

How do I programmatically trigger Flip 3D on Windows Vista and 7?
Is there an API for this and if so, what is it called and where can I find the relevant functions? (I need a specific answer, eg a web link to the actual functions, not something generic like "Oh, it's in DirectX.")
On a related node, I have a Logitech mouse that has a "Document Flip" button that invokes Flip 3D (and then I can press up/down keys to page through the results.) I am curious if they are using an official Windows API or if there is some low level hackery going on.
you need to run a function from dwmapi
Sadly there is no proper funktion name only the ord-number 105
You can try this by executing %WinDir%\System32\rundll32.exe dwmapi #105 from Run-dialog or cmd.
edit
ive found out the Windows' API GetProcAddress Function accepts ord-numbers (the 105) as second parameter as well as proper name
lpProcName [in]
The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.
so use this code
typedef vois (__cdecl *FlipProc)();
HINSTANCE hDwmApi = LoadLibrary(TEXT("dwmapi.dll"));
FlipProcAdd = (FlipProc) GetProcAddress(hDwmApi, (LPCSTR)105);
(FlipProcAdd)();

Resources