I am relatively new at C# and programming in general although I took some C language classes (too) many years ago.
My goal is to call a number of the Windows Color Management functions in my application, to display images to the screen and for saving as TIFFs or JPEGS.
The reason I write today is because I find it a formidable challenge to call these functions? The most challenging part of this task, for me, is to correctly parse the original function calls. Here is the GetICMProfile() declaration :
BOOL WINAPI GetICMProfile(
HDC hDC,
LPDWORD lpcbName,
LPTSTR lpszFilename
);
To be able to successfully call this function in code, I first have to understand what is a "Handle" and what is a "DeviceContext". So far, so good. Now, it took me a while to figure what a LPDWORD was. But I am still stumped by the "lpcb" prefix to "lpcbName"? LPTSTR is a Long Pointer to a TCHAR string. But what is the meaning of the "lpsz" prefix before "Filename"? Searching for "lpcb" or "lpsz" in the context of Win32 API is not trivial. I did find some documentation but I will have to say, it is all cryptic at first blush.
I am coming to my question...
So, in C#, one possible Platform Invoke declaration to the GetICMProfile function is (www.pinvoke.net):
[DllImport("gdi32.dll")]
static extern bool GetICMProfile(IntPtr hDC, ref uint lpcbName,
[Out] StringBuilder lpszFilename);
Seems "reasonable". Staing the declaration is no brainer. To be able to "parse" the declaration is another story. And then, to be able to declare the right variables and code the right function call is another level of magnitude of complexity which acts as a "natural" barrier to entry to the uninitiated, namely me :(
The first line of this declaration is easy, [DllImport("gdi32.dll")]. The second line is where things start to wreak havoc.
Static is easy. extern is easy. bool is easy (although I was reading that BOOL, in the original Win32 function, is a 32bit integer). I get the IntPtr part. I get the hDC part, which is a handle to a DeviceContext (but that comes with its share of problems...).
ref means by reference, I get that. Wish I could understand the meaning of "lpcb" but I suspect it is a Long Pointer which could be coded with another intPtr in C#. The last part is brutal.
First, the [Out]. I was reading about that last night but I still have to wrap my head around its meaning and its behavior during the system call.
Now, I gather that Stringbuilder is class that is "mutable". I learned about C# arrays being immutable (didn't even know such concept could exist before). And there is something about passing the MAX_PATH to that variable? Minus 1, to make up for the presence of a NULL characters? And all this lpszFilename variable, somehow, has to be an array of BYTE?
Add to that, the number of times I read about other people expériences with these ICM functions and the fact, they say, that either the déclarations have bugs or the implementation have bugs, that the function "didn't return anything"?
Makes me Wonder whether I am spending all this time in vain?
Frustrated :(
P.S. Sure hope I posted this in the right Forum