Jump to content
The simFlight Network Forums

Recommended Posts

Posted

Hi Pete,

I'm looking to add a generic keypress simulator to my flight deck interface program so that users can assign hardware switches to mimic a keypress in MSFS. These are not joystick buttons so I'll be creating an xref table where the user can save switch-key mappings. The program will use FSUIPC offset 3200 to send the appropriate key to FS where it will (hopefully) do whatever the user has assigned in FS.

Can you please define or give an example of "wParam" and "lParam" for me? I assume they represent keycodes and modifiers that are to be parameters of an API function but I am unfamiliar with the nomenclature and unsure of which is which (Don't use APIs much in vb.net ). I could not find details in the documentation nor via a search of this forum.

Perhaps you could indicate the value to be written to 3200 for a simple "G" and say "Ctl-K" for me?

Thanks!

Scott L. Fausel, VMD

Posted

Can you please define or give an example of "wParam" and "lParam" for me? I assume they represent keycodes and modifiers that are to be parameters of an API function but I am unfamiliar with the nomenclature and unsure of which is which (Don't use APIs much in vb.net ). I could not find details in the documentation nor via a search of this forum.

They are the parameters for the Windows WM_KEYDOWN and WM_KEYUP messages which you are asking FSUIPC to send on your behalf. The documentation is in the Windows API documentation only (or in multitudes of Windows' programming books), not in any Flight Simulation reference.

When I do any programming in Windows I have to constantly look stuff like this up, I don't learn it. How do you manage without such a reference? I don't understand. Doesn't VB.NET allow you to process Key messages?

If you really cannot find the references, whether in books or in your Compiler's help, I can try to make a copy of some of it here, but I'm not sure that's properly legal.

The keycodes used are those named VK_xxx ("virtual Key") and must be defined somewhere in your compiler's headers if it allows Windows programming. However, the main ones are the same as the key values used by FS in its CFG file and are therefore also listed in my "FSxxxx Controls" documents, and, in fact, in the FSUIPC Advanced User'sa Guide for Key programming.

Get back if you are really stuck, but I am rather puzzled by the question -- the programmer's guide is aimed at programmers and I thought all programmers in Windows would have such data, which is why the documentation is worded to suit. Sorry if this isn't always true.

BTW an alternative to sending Keystrokes is to use the "virtual buttons" facilities in FSUIPC -- offsets 3340 ff. Then the buttons so activated can be programmed in FSUIPC's Buttons page, so saving you the chore.

Regards,

Pete

Posted
They are the parameters for the Windows WM_KEYDOWN and WM_KEYUP messages which you are asking FSUIPC to send on your behalf. The documentation is in the Windows API documentation only (or in multitudes of Windows' programming books), not in any Flight Simulation reference.

Roger. I wasn't sure that they mimicked the Windows API and a quick Google search was unrewarding. I'll search the API docs.

When I do any programming in Windows I have to constantly look stuff like this up, I don't learn it. How do you manage without such a reference? I don't understand. Doesn't VB.NET allow you to process Key messages?

Yes but it is so easy it should be illegal. No API required. I can intercept keyup, keydown and keypress like this:

Function DoSomething(ByVal s as Object, ByVal e asKeyEventArgs) Handles MyBase.KeyDown

...Do something with e.keycode and e.Shift, etc - all enumerated for me

End Function

Sending is just as easy using built in "SendKeys" function - in fact you can use enumeration syntax e.g. {Backspace} and even avoid keycodes.

DotNet has obviated 99% of the Windows API (in fact it will probably become legacy in next release - 'Longhorn').

If you really cannot find the references, whether in books or in your Compiler's help, I can try to make a copy of some of it here, but I'm not sure that's properly legal.

I'm sure I can find them now that I know they are WIndows API terms.

The keycodes used are those named VK_xxx ("virtual Key") and must be defined somewhere in your compiler's headers if it allows Windows programming. However, the main ones are the same as the key values used by FS in its CFG file and are therefore also listed in my "FSxxxx Controls" documents, and, in fact, in the FSUIPC Advanced User'sa Guide for Key programming.

I'm not quite sure about what you mean by defining keycodes here. VB.net has no header file. Won't my program just need to "know" (e.g. via constant definitions) that keycode 112 = F1, etc? I have copies of the sections you mention but the application will capture the keycode information in the section that accepts user input for the key(s) to be mapped to a particular switch i.e. "recording mode"

Get back if you are really stuck, but I am rather puzzled by the question -- the programmer's guide is aimed at programmers and I thought all programmers in Windows would have such data, which is why the documentation is worded to suit. Sorry if this isn't always true.

Well, that's cause I let dotnet do all that dirty work for me . I guess it might be considered "cheating" by some but it sure saves me time to foucs on other programming issues ! Where I run into issues is in trying to interface with COM code conventions - as in this case.

BTW an alternative to sending Keystrokes is to use the "virtual buttons" facilities in FSUIPC -- offsets 3340 ff. Then the buttons so activated can be programmed in FSUIPC's Buttons page, so saving you the chore.

That's a great idea and I will probably offer both. My application handles a fair amount of stuff not modeled in FS or PM but some folks might just want basic interface stuff. That would essentially let me model my inputs as joystick buttons for functions I may not yet have coded.

Thanks!

Scott

Posted

Yes but it is so easy it should be illegal. No API required. I can intercept keyup, keydown and keypress like this:

Function DoSomething(ByVal s as Object, ByVal e asKeyEventArgs) Handles MyBase.KeyDown

...Do something with e.keycode and e.Shift, etc - all enumerated for me

End Function

Ah, I hate all thsat high level stuff. It does the same things as it always did, yet in much more convoluted and expensive ways. It is this sort of development that means that the vast improvement we get in computer speeds and capacity is all but totally lost to code inflation and inefficiency. I am afraid I am a die-hard assembly-level programmer who uses C with some reluctance, but at least in C I've a fair notion of what is really happening!

I don't mean any of this as an insult to you. I do realise that this makes coding simple and easy, but the cost is horrendous, both as a loss of understanding in most programmers about what actually happens and in the bloat I already mentioned.

I'm not quite sure about what you mean by defining keycodes here.

Sorry, if Virtual Keycodes are never used in VB.net I am rather at a loss to explain them to you. Surely you don't distinguish between, say, ESCAPE and ENTER by using their numeric representations? Most languages, even Assembly Code, uses names for common constants -- doesn't VB? In the C and C++ headers the Keycodes are defined by #defines with names like VK_ESC or whatever. Then you need not worry that this is in fact number 27, or whatever.

Regards,

Pete

Posted

Ah, I hate all thsat high level stuff. It does the same things as it always did, yet in much more convoluted and expensive ways. It is this sort of development that means that the vast improvement we get in computer speeds and capacity is all but totally lost to code inflation and inefficiency. I am afraid I am a die-hard assembly-level programmer who uses C with some reluctance, but at least in C I've a fair notion of what is really happening!

I don't mean any of this as an insult to you. I do realise that this makes coding simple and easy, but the cost is horrendous, both as a loss of understanding in most programmers about what actually happens and in the bloat I already mentioned.

No insult taken (in my case I believe it's not a loss of understanding but a divergence of language and syntax) and we could probably fill an entire discussion forum with programming debates .

However IMO you are overstating the cost of "code inflation and inefficiency." The dotnet framework is actually equal in efficiency and speed to unmanaged C++. Managed code (be it C++, C# or VB) is all compiled to a common intermediate language that is fed to the JIT (just in time) compiler. The resultant compilation is as fast and efficient as compiled C.

All of the "bells and whistles" are rapid development tools only. The intermediate language that results is "lean and mean" and dotnet programs are far from "bloated."

I dabbled a bit in 8086 assembler way back when and still program PICs in assembler so I know how you feel - kind of like digging in the garden vs. picking out veggies at the market .

Nonetheless with high level RAD languages like vb.net I can cut my development time enormously. And I do indeed know what is really happening - it's still full of Do and For loops and function calls, etc. What's improved is the standardization - namespaces, classes, etc. It is now very easy to look up the hierarchy of an object or method and figure out how to use it.

Sorry, if Virtual Keycodes are never used in VB.net I am rather at a loss to explain them to you. Surely you don't distinguish between, say, ESCAPE and ENTER by using their numeric representations? Most languages, even Assembly Code, uses names for common constants -- doesn't VB? In the C and C++ headers the Keycodes are defined by #defines with names like VK_ESC or whatever. Then you need not worry that this is in fact number 27, or whatever..

Yes - simply called "Constants" in VB like so:

Public CONST ESC_KEY = 27

But it's unnecessary as these are already defined in a dotnet enumeration (keyChar) for me:

labelKey.text = e.KeyChar (displays actual key e.g. "K" in label)

where e is the argument passed to my function automatically if this function handles the keypress event. I can also obtain e.KeyValue integer representation of the key (i.e. keycode).

That's an example of the opposite of "code bloat" - I do not need to add a keycode/value constant map to my code as you would in C - it's already embedded in the framework (within the forms namespace)

Anyway, I still haven't had a chance to review the API to see how 3200 wants those parameters formatted. Hope to get to it tonight. Thanks for the lively discussion !

Regards,

Scott

Posted

What's improved is the standardization - namespaces, classes, etc. It is now very easy to look up the hierarchy of an object or method and figure out how to use it.

Ah, well, that's where I get lost and switch off. I'm still strictly a bottom-up procedural programmer. OOP lost me way back. After 41 years of solidly programming the "old-fashioned way" I have no inclination to change now. And as for productivity, well, maybe I can't make a smart user interface as fast as you clever young(er) chaps, but I bet I can solve programming problems in real code faster than just about anyone! :wink:

But I understand where you are at, and why. It's just not somewhere I want to be now, and I guess we will just have to differ about "bloat" and leave it at that. I've disassembled enough of FS's newer code (C++ produced) to see how convoluted and inefficient it is compared to the original (mixture of standard C and ASM, the C parts derived from the original ASM of early years). I reckon FS would be many times more efficient done the "old-fashioned" way, but it would have probably taken them longer -- though using a *smaller* team, not *bigger* might have helped. OOP and all that stuff is probably great for team-built software, it's just that I've always been a "loner", and look for maximum efficiency in the code, not in the development time. Yes, very non-commercial (good job I'm no longer involved in truly commercial projects and can indulge in it more as a hobby, eh? :) ).

That's an example of the opposite of "code bloat" - I do not need to add a keycode/value constant map to my code as you would in C

None of that would be "code" as such in any case, just instructions to the compiler, not the processor. And, no, Windows C/C++ programmers don't have to define things like VK codes. That's the point. They use the names, they don't have to remember the numbers. The names are pre-defined, just as the API procedures are. That's why I couldn't give you your example without looking the values up. I don't use the values that you seem to need.

Regards,

Pete

Posted

And, no, Windows C/C++ programmers don't have to define things like VK codes. That's the point. They use the names, they don't have to remember the numbers. The names are pre-defined, just as the API procedures are. That's why I couldn't give you your example without looking the values up. I don't use the values that you seem to need.

Actually, nor do you in VB. To read a keystroke in VB - assuming you want to know what 'key' was pressed, rather than what letter, etc, was returned, you use the KeyUp or KeyDown events, and the predefined key names.

Private Sub Control_KeyDown(KeyCode As Integer, Shift As Integer)

This will return two values when a key is pressed - KeyCode for which key is pressed, and Shift for which of the Shift, Ctrl or Alt keys are down at the same time.

While KeyCode does return an integer, you don't actually use it. To decide what to do with the input, you usually then just use the pre-defined key names in a case list.

Select Case KeyCode
Case vbKeyF1
strKey="The F1 key was pressed"
Case vbKeyF2
strKey="The F2 key was pressed"
...... etc, etc, etc

Richard

Posted

Rick pointed out the VB5/6 way of grabbing key codes and I think we can all agree that each language implements a way of capturing these and enumerating them.

OK, I've waded through the API docs and here is where I am at:

1. WM_KEYDOWN is &H100 and WM_KEYUP is &H101

2. wParam specifies virtual keycode of the key to be sent

3. lparam specifies repeat count and several other items.

Question 1: bits 16-23 of lparam specify the device dependent scan code...seems not useful as we already have virtual KC. Can we simply use lparam bits 0-15 for repeat count and zero the rest of the double word e.g. lparam = 0 if there are to be no repeats (and assuming not an extended key as set in bit 24)?

Question 2: Is it correct to say that to transmit a "shift-K" I would send a WM_KEYDOWN + &H10 + 0 followed by WM_KEYDOWN + &H48 + 0 and then the corresponding KEYUPs to simulate holding the while "K" is depressed (&H10 is VKC for shift and &H48 is vkc for K)?

Question 3: The FSUIPC guide indicates that all 12 Bytes must be written in "one IPC write." In the fsuipc VB.net sdk writing an offset is done via a Write followed by a Process. Can I write to 3200, write to 3204, write to 3208 and then process? Or are you saying I have to write 12 Bytes to 3200 in one function call - is that even possible given the largest data structure (Long or Double) is 8 bytes? Or do I use a 12 element byte array?

Sorry - I know my lack of familiarity with C and the Windows API are making this stuff murkier to me than it should be though I think I've just about got it.

Thanks for your help,

Scott

Posted

Question 1: bits 16-23 of lparam specify the device dependent scan code...seems not useful as we already have virtual KC. Can we simply use lparam bits 0-15 for repeat count and zero the rest of the double word e.g. lparam = 0 if there are to be no repeats (and assuming not an extended key as set in bit 24)?

I think you can omit the scan code -- if not I think there is a Windows API which will give you a scan code for a virtual key code. Without experimenting with it I'm afraid I cannot be more exact. This feature was programmed into FSUIPC several years ago, and I use it in WideClient (as it says), but without going through code I really couldn't say. All FSUIPC does is use a facility in Windows to put the values through to FS. In case you want to look that up, it is the "SendInput" API.

Question 2: Is it correct to say that to transmit a "shift-K" I would send a WM_KEYDOWN + &H10 + 0 followed by WM_KEYDOWN + &H48 + 0 and then the corresponding KEYUPs to simulate holding the while "K" is depressed (&H10 is VKC for shift and &H48 is vkc for K)?

Why not use the names for the Keycodes as Rick says you can? Seems odd, if you have them defined in VB, to have to revert to numbers after all we discussed on this.

I normally find out what sequences are needed, to make sure I get the order correct, by using the Spyxx program that comes with MS Visual Studio and seeing the actual sequences when I press the real buttons I want to use. I find this is the only accurate way. However, that said, I seem to recall that, yes, you's do Shift-down, Char-down, Char-up, Shift-up. Horrible, isn't it?

Of course, WideClient, my user of the facility, doesn't have much complication as all it is doing is relaying real WM_KEYDOWN and WM_KEYUP messages it receives on the Client PC to FS via the 3200 offset. All it needs to do is copy the wParam and lParam it receives. Similarly, those writing keynoard emulators normally need to know all this stuff in any case, to get keypresses into other programs. I think this is actually the first time anyone has wanted to use this facility with no prior knowlegde at all.

Question 3: The FSUIPC guide indicates that all 12 Bytes must be written in "one IPC write." In the fsuipc VB.net sdk writing an offset is done via a Write followed by a Process.

Really? For every individual read and write? That is GROSSLY inefficient! Each "Process" call does a Process change to get into FS, activates FSUIPC's offset scanning, processes your changes, then needs another process change back to your program! The whole reason the FSUIPC_Read and FSUIPC_Write procedures were split from the FSUIPC_Process procedure was to allow EVERY read and write you needed to do to be performed in one process. For instance, if your program operates on a 55 mSec cycle (the most usual, based on the standard windows TIMER facility which ticks at 18Hz), you'd build up the complete set of Reads and Writes then do one Process call for the lot, in each such cycle.

If all VB programs operate one read or write, one process, then I am not surprised they all seem so slow and inefficient to me -- I thought it was just the horrible code ther compiler was producing! :o

Can I write to 3200, write to 3204, write to 3208 and then process?

No, that won't work in this case. The complete structure of three values is one data value.

Or are you saying I have to write 12 Bytes to 3200 in one function call - is that even possible given the largest data structure (Long or Double) is 8 bytes? Or do I use a 12 element byte array?

The largest structure is 8 bytes!!!? Surely you mean the longest single data type, not structure?

The 12 bytes should be defined as a simple 3 32-bit integer structure or array. Don't tell me VB.NET doesn't support structures at all? If not, then surely it must have integer arrays? At least in this instance all three parts are the same size, so an array would do. But it doesn't have 12 elements, only 3 -- the three 32 bit values (unsigned really, in Windows, but I don't suppose VB.Net supports unsigned values either -- or does it?)

By "one write" it means "one write" -- i.e. one call to the FSUIPC_Write procedure, or whatever it is called in VB.NET, to write the 12 bytes, no matter how you manage to cobble them together before hand.

Sorry - I know my lack of familiarity with C and the Windows API are making this stuff murkier to me than it should be though I think I've just about got it.

I can see why no one can use Windows APIs in VB.NET then -- if it doesn't support structures then a large portion of the Windows API is unusable, as it is very structure dependent. :(

Regards,

Pete

Posted
PetDoc:In the fsuipc VB.net sdk writing an offset is done via a Write followed by a Process
Pete:Really? For every individual read and write? That is GROSSLY inefficient! Each "Process" call does a Process change to get into FS, activates FSUIPC's offset scanning, processes your changes, then needs another process change back to your program! The whole reason the FSUIPC_Read and FSUIPC_Write procedures were split from the FSUIPC_Process procedure was to allow EVERY read and write you needed to do to be performed in one process.

No, the SDK just looks like that because the example only has one Write, so it's Write then Process.

My VB apps go Read, Read, Read, Write, Write, Write, Process.

Richard

Posted
I think you can omit the scan code -- if not I think there is a Windows API which will give you a scan code for a virtual key code.

Indeed there is but I'll try without it at first.

Why not use the names for the Keycodes as Rick says you can? Seems odd, if you have them defined in VB, to have to revert to numbers after all we discussed on this.

That was just for example - actually I'd just pass the variable that I stuffed the code into when originally captured.

I normally find out what sequences are needed, to make sure I get the order correct, by using the Spyxx program that comes with MS Visual Studio and seeing the actual sequences when I press the real buttons I want to use. I find this is the only accurate way. However, that said, I seem to recall that, yes, you's do Shift-down, Char-down, Char-up, Shift-up. Horrible, isn't it?.

Good idea, thanks and yes it is quite horrid!

Of course, WideClient, my user of the facility, doesn't have much complication as all it is doing is relaying real WM_KEYDOWN and WM_KEYUP messages it receives on the Client PC to FS via the 3200 offset. All it needs to do is copy the wParam and lParam it receives. Similarly, those writing keynoard emulators normally need to know all this stuff in any case, to get keypresses into other programs. I think this is actually the first time anyone has wanted to use this facility with no prior knowlegde at all.

Yes, well that's because no API knowledge is required to do this stuff in dotnet

Really? For every individual read and write? That is GROSSLY inefficient! Each "Process" call does a Process change to get into FS, activates FSUIPC's offset scanning, processes your changes, then needs another process change back to your program! The whole reason the FSUIPC_Read and FSUIPC_Write procedures were split from the FSUIPC_Process procedure was to allow EVERY read and write you needed to do to be performed in one process. For instance, if your program operates on a 55 mSec cycle (the most usual, based on the standard windows TIMER facility which ticks at 18Hz), you'd build up the complete set of Reads and Writes then do one Process call for the lot, in each such cycle.

If all VB programs operate one read or write, one process, then I am not surprised they all seem so slow and inefficient to me -- I thought it was just the horrible code ther compiler was producing! :o

Oops, no sorry - you misunderstand me. The dotnet fsuipc sdk works the same way. However there are frequently times when one cannot queue reads and writes. For example, many functions need the information from a read (or reads from several different offsets) prior to writing some data because the data is dependent upon what is read (such as functions that toggle one bit in a Word or branch depending upon the data read). Thus you must process the read or reads before writing otherwise you don't know what to write.

I could potentially code a static boolean flag into each function that postpones writes such that only every other time the dispatcher calls the function it performs the writes. Each cycle would have its own group process. One issue is that many functions share a common helper function which currently (re)creates a token that would lead to conflicts if the function executed more than once in a process cycle. However I could have the parent function pass in token and result parameters to keep them unique. Ok, I see a lot of debugging and testing ahead but yes I would love to eliminate single read/write processing from my code altogether!

No, that won't work in this case. The complete structure of three values is one data value.

The largest structure is 8 bytes!!!? Surely you mean the longest single data type, not structure?

Yes, sorry - was referring to a data type, not a structure. Poor choice of words but it was getting a bit into the wee hours when I wrote that!

The 12 bytes should be defined as a simple 3 32-bit integer structure or array. Don't tell me VB.NET doesn't support structures at all? If not, then surely it must have integer arrays? At least in this instance all three parts are the same size, so an array would do. But it doesn't have 12 elements, only 3 -- the three 32 bit values (unsigned really, in Windows, but I don't suppose VB.Net supports unsigned values either -- or does it?)

By "one write" it means "one write" -- i.e. one call to the FSUIPC_Write procedure, or whatever it is called in VB.NET, to write the 12 bytes, no matter how you manage to cobble them together before hand.

Actually, the vb.net implementation of structures is very robust - they are basically classes without some of the bells & whistles. Much improved from VB6 User defined types. However I don't know that I could pass such a structure to the fsuipc.write function - I don't see an overload for it in Bob's SDK code. That's what prompted my concern about a 12 byte value - the sdk write function appears to only accept 1-, 2-, 4- and 8-byte values plus byte arrays.

My thought was passing a 12 element array of single bytes - would that fit your definition of "cobble together" ? It's no problem to create a 3 element arrray of 32 bit unsigned values (Long in vb.net - and yes, it does support unsigned values) - I just don't know if the SDK fsuipc.write function can accept such an array of Long Integers.

I can see why no one can use Windows APIs in VB.NET then -- if it doesn't support structures then a large portion of the Windows API is unusable, as it is very structure dependent. :(

I have passed structures to the API in my programs via a C++ function library in order to interact with another developer's USB input board. The difference is that I wrote the wrapper function signature so as to solicit a structure as a parameter whereas the fsuipc vb.net sdk does not appear to have a write function with a structure as the data parameter. I'll have to check with Bob Scott about passing structures to fsuipc from vb.net. If this cannot be done via a byte array then I will work on coding a function that will accept structures and adding it to the sdk.

Thanks,

Scott

Posted

the sdk write function appears to only accept 1-, 2-, 4- and 8-byte values plus byte arrays.

How does it know what they are? The interface just wants an address and a byte size. It doesn't care at all what the data in or how it is composed. A 12 byte array might be 12 bytes, 6 16-bit words, 3 32-bit ones, or some weird mixture. All it wants is an address and size so it can keep building the block which will be sent by the Process call.

I have passed structures to the API in my programs via a C++ function library in order to interact with another developer's USB input board. The difference is that I wrote the wrapper function signature so as to solicit a structure as a parameter whereas the fsuipc vb.net sdk does not appear to have a write function with a structure as the data parameter.

The SDK contains all the information about the FSUIPC interface and all the source code. It even has the source code for the libraries supplies for C/C++ programmers -- but in the case of VB and VB.NET and so on I understood it was only source code. Surely you do whatever you like with it. It is only trying to help folks understand how to interface to FSUIPC. No one is making any restrictions as far as I know.

I'll have to check with Bob Scott about passing structures to fsuipc from vb.net. If this cannot be done via a byte array then I will work on coding a function that will accept structures and adding it to the sdk.

You've lost me here. It sounds as if VB.NET is really very restrictive to programming. All the FSUIPC interface needs is an address and a size. I would have thought that's all the parameters to the calls needed to be, whatver the real data is. I know there's a problem in VB about passing pointers to strings, which is why the WriteS function was added. That seemed a bit odd to me too, but you seem to imply that it goes much much further. Ugh.

Regards,

Pete

Posted
How does it know what they are? The interface just wants an address and a byte size. It doesn't care at all what the data in or how it is composed. A 12 byte array might be 12 bytes, 6 16-bit words, 3 32-bit ones, or some weird mixture. All it wants is an address and size so it can keep building the block which will be sent by the Process call.

...All the FSUIPC interface needs is an address and a size. I would have thought that's all the parameters to the calls needed to be, whatver the real data is. I know there's a problem in VB about passing pointers to strings, which is why the WriteS function was added. That seemed a bit odd to me too, but you seem to imply that it goes much much further. Ugh.

Yes, that is the crux of the biscuit. Unlike C++, VB.net is based upon a *managed* memory scheme. Except for some little advertised workarounds, dotnet does not use pointers to memory. It is all mapped and managed by the system. A benefit is the elimination of circular reference and other induced memory leaks but the cost is inflexibility in interacting with unmanaged code. The following is an excerpt from a previous Bob Scott Post:

The pesky FSUIPC_Get was written to allow VB.Net to place the results of FSUIPC_Read operations into a managed data structure which is compatible with the .net memory management system. The basic approach is to pass the FSUIPC_Read a reference to a table offset token, and the function returns the offset into the local, .net-managed buffer which will contain the result after the FSUIPC_Process call. The FSUIPC_Get function retrieves the value at the specified offset from the local r/w buffer.

This was necessary because just passing FSUIPC_Read a pointer to a variable as in previous versions will not work with the .Net heap manager moving things around. The referenced variable may be moved by the heap manager in the interval between when the FSUIPC_Read and the FSUIPC_Process calls are made, leaving one with a nasty dangling pointer problem.

...the first param in the FSUIPC_Get call is the integer offset token returned by FSUIPC_Read, the second param is a reference to the var where the actual result will be passed. The overloaded function defs will pass the correct size/type of data based on the type of the second param used in the call, except for passing of arrays where number of bytes to return must be explicitly coded.

So you see the size/type is needed for the dotnet sdk functions - not the "raw" fsuipc Read or write. But re-reading Bob's post made me realize that we should be able to write a 12 element Byte array to 3200 by using the Byte() overload of FSUIPC_Write and setting size to 12.

You can also see how queuing reads for a group process becomes more complex when one has to retrieve all data with unique tokens in individual "Get" functions after a Process call. Makes shared helper functions much more difficult to code. Theoretically one can "pin" managed memory and protect it from the system's "shuffles" but Bob reported he tried valiantly but unsuccessfully to make that work correctly before resorting to the buffered table.

Well, time to put this to the test. I'll keep you posted.

Regards,

Scott

Posted

Yep, that did it. For the sake of those still following along or searching the forum in the future, here's the summary for programming Offset &H3200 via vb.net:

1. Create a 12 element Byte array.

2. Stuff elements 0-3 with Bytes 0-3 of message (&H100 or CONST WM_KEYDOWN for keydown, &H101 or CONST WM_KEYUP for keyup. I stripped the bytes out of the LONG integer via a for/next loop, the ">>" operator, an &HFF mask and the CByte() function.

3. Likewise stuff elements 4-7 with Bytes 0-3 of the virtual keycode you are sending (e.g. &H47 for the letter "G").

4. ibid for elements 8-11 and Bytes 0-3 of lParam (0 unless you are looking to send repeats i.e. "acceleration").

5. Write the byte array to fsuipc:

FSUIPC_Write(&H3200, 12, KeyData, t_keyData, _intError)

where KeyData is the resultant byte array.

6. Process when appropriate.

Seems obvious once it's figured out but then I suppose most things do !

-Scott

Posted

The more I read about .NET, the more convinced I am I should stick with Legacy VB as long as humanly possible. In my case I have little choice anyway - my video editing hardware has no drivers available for anything after Win98, so I can't shift to .NET for my own usage.

To be honest, I really can't understand why anyone has already shifted to writing in .NET - as long as there is still a large Win98 / Win95 user base out there who can't use .NET based software I would think anyone who wanted to write widely distributable software would stick to a language that all OS's can run.

Richard

Posted
The more I read about .NET, the more convinced I am I should stick with Legacy VB as long as humanly possible. In my case I have little choice anyway - my video editing hardware has no drivers available for anything after Win98, so I can't shift to .NET for my own usage.

To be honest, I really can't understand why anyone has already shifted to writing in .NET - as long as there is still a large Win98 / Win95 user base out there who can't use .NET based software I would think anyone who wanted to write widely distributable software would stick to a language that all OS's can run.

Richard

Well Richard, we're off topic now but I'll give you my $0.02. Many folks made similar comments regarding the move from DOS to Windows - why write Windows-based code when DOS was faster/better/?

VB.net is a quantum leap from VB6. Exception handling, Garbage collection, true OOP, xcopy deployment (no need for the registry), built in base class libraries, structures vs User defined types are all major improvements and there are many more. ADO.net makes data-driven web programming enormously easier and you can cater to all web clients.

Yes, you do make a choice to target Win2k+ for non-web applications. That's a personal decision you must make after weighing the pros and cons of the improvements vs. the reduction in client scope. Another large factor is the learning curve - much of VB.net (especially OOP) is very different than VB and it's a steep climb. Well worth it IMHO.

-Scott

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.