Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: How to use Windows Api? (Read 9511 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How to use Windows Api?

I am having a lot of trouble properly doing plugin for foobar2000 in 0.9SDK(VS2005),but there are some error when i
use windows api,

eg:
{
    char TempChar[255],ExeDir[255];
    GetPrivateProfileString("Test","Dir","",TempChar,255,ExeDir);
}

1.   error C2664: 'GetPrivateProfileStringW' : cannot convert parameter 1 from 'const char [12]' to 'LPCWSTR'   d:\cpp\foobar0.9\foobar2000\foo_tutorial1\step1.cpp   471

Who can tell me How to use windows api?
Thanks!

How to use Windows Api?

Reply #1
The problem you've got there is that you are passing a char buffer to a unicode function that expects a wide buffer (of type WCHAR). Either use wide characters, or change your project settings to "Use Multi-Byte character set". However if you do this, be careful passing strings from foobar2000 to the windows Api, as they are UTF8 encoded and windows will not understand any foreign characters in them. For most things you'd want to do, the fb2k SDK defines nice wrappers that convert strings then call the win32 function, these are defined in pfc.h? (from memory) and are named the same as the API function they represent but with u infront, for example uDeleteFile();

Also, I'm not sure why you are calling GetPrivateProfileString(). What are you trying to do? This function reads a string from an .ini file, and according to the MSDN should not be used.

Finally, for a buffer that will be used to store a file/directory path, use MAX_PATH as the size. Your code would fail in the case of a very long filename.

How to use Windows Api?

Reply #2
The problem you've got there is that you are passing a char buffer to a unicode function that expects a wide buffer (of type WCHAR). Either use wide characters, or change your project settings to "Use Multi-Byte character set". However if you do this, be careful passing strings from foobar2000 to the windows Api, as they are UTF8 encoded and windows will not understand any foreign characters in them. For most things you'd want to do, the fb2k SDK defines nice wrappers that convert strings then call the win32 function, these are defined in pfc.h? (from memory) and are named the same as the API function they represent but with u infront, for example uDeleteFile();

Also, I'm not sure why you are calling GetPrivateProfileString(). What are you trying to do? This function reads a string from an .ini file, and according to the MSDN should not be used.

Finally, for a buffer that will be used to store a file/directory path, use MAX_PATH as the size. Your code would fail in the case of a very long filename.


Thank You;
I want reads a string from an .ini file use GetPrivateProfileString(),but can't find reads a string from an .ini file in fb2k SDK;

How to use Windows Api?

Reply #3
I want reads a string from an .ini file use GetPrivateProfileString(),but can't find reads a string from an .ini file in fb2k SDK;


For what purpose is the ini file? If it is to store your component's settings, it is much tidier and more convenient (for both you and the component's users) to store settings using the foobar2000 config APIs. See cfg_var.h in the SDK for more details.

How to use Windows Api?

Reply #4
For what purpose is the ini file? If it is to store your component's settings, it is much tidier and more convenient (for both you and the component's users) to store settings using the foobar2000 config APIs. See cfg_var.h in the SDK for more details.


I had saw cfg_var.h, but it's not use to me.
I save some options to ini file,and want load form ini file,but don't know how to load?
Before i can use "GetPrivateProfileString" in sdk 0.8,but now can't use window's api in sdk0.9.
Who can help me?

How to use Windows Api?

Reply #5
I save some options to ini file


This is your problem, you have no good reason to write to an ini file, especially if you're going to concoct your own substandard code (ever read "the ten commandments of C", especially number 7?)

Instead of saving options to an ini file, just save it to a cfg_var. Easier to use, easier to manage. And you won't have to worry about errors in the cfg.

How to use Windows Api?

Reply #6
This is your problem, you have no good reason to write to an ini file, especially if you're going to concoct your own substandard code (ever read "the ten commandments of C", especially number 7?)

Instead of saving options to an ini file, just save it to a cfg_var. Easier to use, easier to manage. And you won't have to worry about errors in the cfg.


Thanks!
"Save it to a cfg_var",how to use cfg_var?Can you offer some code to me?

How to use Windows Api?

Reply #7
how to use cfg_var?
It's really quite simple. I see you're working from Foosion's tutorial component. He provides an cfg_var example at the top of his file (look at lines 70-78). The SDK readme and SDK/SDK/cfg_var.h also provide useful information. In your example, you seem to want to save off a string. Therefore, the cfg_var type you need is a cfg_string. The first step is to generate a GUID (using guidgen.exe):
Code: [Select]
// {00000000-0000-0000-0000-000000000000}
// USE THE GUID created from GUIDGEN, not this one.
static const GUID <<name>> =
{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };

Give your GUID a name (replace the <<name>> portion of it):
Code: [Select]
// {00000000-0000-0000-0000-000000000000}
static const GUID guid_cfg_TempChar = { ... /* as before */ };

Now declare a static global variable of type cfg_string:
Code: [Select]
static cfg_string cfg_TempChar(...);

What do we put inside the brackets (where those ...s are)? The first parameter is a guid (this is the going to be the key that foobar2000 will put in the cfg). We can use the GUID we created earlier:
Code: [Select]
static cfg_string cfg_test_dir(guid_cfg_TempChar, ...);

The second parameter is the default value for the cfg (This will be the value of the cfg_ if it doesn't exist in cfg yet). Put in the default that you want the parameter to take:
Code: [Select]
static cfg_string cfg_test_dir(guid_cfg_TempChar, "V:\\");

This should leave your final code looking something like this:
Code: [Select]
// This was the GUID that GUIDGen spat for me when I ran it
// just now. It's going to be different with yours
static const GUID guid_cfg_TempChar =
{ 0x2fb8448f, 0xa689, 0x4d35, { 0xb9, 0x6, 0x4b, 0x44, 0x4, 0x73, 0x94, 0xcc } };
static cfg_string cfg_test_dir(guid_cfg_TempChar, "V:\\");

If you want to set the value do this:
Code: [Select]
cfg_test_dir = "Whatever";

If you want to retrieve the value you can do this:
Code: [Select]
const char *ExeDir = cfg_test_dir

And Foobar2000 will take care of the rest. For non-string datatypes, you have cfg_int, cfg_bool, even a generic cfg_struct<>.


 

How to use Windows Api?

Reply #9
There are many different ways to read an .ini file, and they are not at all hard to parse. If a line starts with '[', its a section name. Anything else not beginning with ';' (a comment) is a key, and if there is an '=' it is followed by the value.

To read the file, you could use the windows API, CreateFile,ReadFile and CloseHandle, or the C stdio library, fopen, fread/fscanf/fgets and fclose, or iostreams' ifstream. It's up to you how you read the file, and how you parse it.

However this really is a very basic application of C/C++, any decent tutorial on the web, or a book on C/C++ will show you how to read a file, manipulate and parse strings (and how to be safe with them, especially if you use *scanf).

How to use Windows Api?

Reply #10
Although it is relatively easy to parse an ini file, it becomes extremely difficult to reliably parse an ini file.

If a line starts with '[', its a section name. Anything else not beginning with ';' (a comment) is a key, and if there is an '=' it is followed by the value.


Although Windows ini files (those which can be read by GetPrivateProfile*) have a strict format, the same is not true for some other ini formats I have seen.

Problems begin when an ini file has a syntax error in the file. For example when a '[' identifier doesn't have a closing ']' (or even worse, a '[['). Failure to account for such files could result in failure. Comments needn't necessarily begin with ';' (although GetPrivateProfile* inis do), some can begin with # (or // or <!-- or ...).

Then there's the UTF8 / UTF16 BOM problem and files that have UNIX style newlines. Worse is a file that inconsistently uses '=' (some don't use '='s, some use tabs or double spaces). And does anyone's know if ini files should be case sensitive or not?

If you're going to be reading data from ini files, you'd better have sensible defaults for your settings, because in all likelihood, you won't get them from the ini file.