Results 1 to 20 of 20

Thread: [RESOLVED] Windows 7 API Problems

  1. #1

    Thread Starter
    Fanatic Member Vectris's Avatar
    Join Date
    Dec 2008
    Location
    USA
    Posts
    941

    Resolved [RESOLVED] Windows 7 API Problems

    My problem is with the following API.

    Code:
        Private Declare Function GetKeyState Lib "user32" (ByVal keyCode As Integer) As Integer
    In Windows XP, I could simply use the API like this:

    Code:
     If GetKeyState(Keys.Left) < 0 Then 'Move Left
    If the key was pressed, it was a certain number below 0, the number itself alternated each time you pressed the key but it was always below 0.

    My problem is that in Windows 7, when you press the Left key, the number isn't the same, in fact the number isn't even negative anymore. This problem tricked me at first into thinking the API didn't even work as when I ran the .exe of course my code did nothing since GetKeyState never returned a number below 0. I tested the value itself though and found that it never goes negative, the number for the key just decreases a little.

    The weird thing is, while the .exe from the Debug folder proved my point that the GetKeyState number was different and thus the program didn't work, running the .exe from the Release folder actually worked, the controls were fine and the API returned numbers less than 0 for GetKeyState. But the .exe from the release folder was built with my old XP computer, as soon as I made a new build with my windows 7 computer the API stopped working again.

    I searched the site and googled but didn't find anything on this problem. Does anyone know what's going on? Why did Windows 7 change the number returned for when the key is down, is there a way to change it back without having to include some large package with my program? Why did the build from my XP computer work at first? Also it was only the one from the release folder, not the debug one, even though they were both from the XP computer.

    EDIT: I tested some more on windows 7 and found that every time I run the program, the number returned by GetKeyState is completely different. When the key is down the number is 1,000,000 units higher than up, but other than that the number is random each program start.
    Last edited by Vectris; Jul 11th, 2010 at 12:53 AM.
    If your problem is solved, click the Thread Tools button at the top and mark your topic as Resolved!

    If someone helped you out, click the button on their post and leave them a comment to let them know they did a good job

    __________________
    My Vb.Net CodeBank Submissions:
    Microsoft Calculator Clone
    Custom TextBox Restrictions
    Get the Text inbetween HTML Tags (or two words)

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Windows 7 API Problems

    Are you sure you should even be using the GetKeyState function? More likely, you should be using the GetAsyncKeyState function. If you really should be using GetKeyState then you're using it incorrectly. It actually returns a Short, not an Integer, and it's not the actual value of that number that matters. It's only the value of the high-order and low-order bits. That's why the numbers seem different: because most of the bits in those numbers are irrelevant. This is another example of why you must ALWAYS read the documentation.

  3. #3

    Thread Starter
    Fanatic Member Vectris's Avatar
    Join Date
    Dec 2008
    Location
    USA
    Posts
    941

    Re: Windows 7 API Problems

    This is the GetAsyncKeyState function, I just renamed the function to be shorter. As for the return value, that makes sense because my new computer is 64-bit and my old 32 so I'm guessing that's why the values are different.

    But I'm still curious, why did the build from my old computer work but not the one from my new? I hadn't changed any code so it makes no sense that using < 0 would all of the sudden work.

    I suppose I'll be taking a look at the documentation to see if it can sort this out but jmc, do you have any ideas on how I could code the getkeystate function so that it will work the same way on 32 and 64 bit computers?

    EDIT: I looked at the msdn library page and according to them, the most significant bit means the key is down and the least means its up. This is strange because that wasn't true on my 32-bit computer where a negative number was returned when the key was down. It is true however for the 64-bit as the number increases when it's down. Am I looking at it wrong?

    EDIT2: Ok I took a second look at the API and realized I was using type integer instead of ushort like the API suggested. After switching to ushort, the value immediately became 0 while the key was up, and then just a random integer greater than 0 when the key was down. This test was on the 64-bit computer so I don't know for sure yet if its the same for 32-bit but if so this solves my problem.

    Also I did some more searching and found out there actually is a function called just GetKeyState, looks like renaming APIs to be shorter isn't a good idea.

    The only remaining question I have is about the different build working the first time. Other than that I just need to test using type ushort on a 32-bit computer to see if the return value is still 0 for up and greater than 0 for down.

    Thanks jmc
    Last edited by Vectris; Jul 11th, 2010 at 12:48 PM.
    If your problem is solved, click the Thread Tools button at the top and mark your topic as Resolved!

    If someone helped you out, click the button on their post and leave them a comment to let them know they did a good job

    __________________
    My Vb.Net CodeBank Submissions:
    Microsoft Calculator Clone
    Custom TextBox Restrictions
    Get the Text inbetween HTML Tags (or two words)

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Windows 7 API Problems

    You can't just use an arbitrary name for an API function like that. Think about it. If you specify a library and a function name, how is the system supposed to know which function you want to call if the names don't match? The answer is by use of the Alias keyword, which you haven't used. As such, you are calling the function in that library with the name you specify, i.e. GetKeyState. If you use a name that doesn't exist then the call will fail.

  5. #5
    Fanatic Member TTn's Avatar
    Join Date
    Jul 2004
    Posts
    685

    Re: Windows 7 API Problems

    I have not seen this problem while using Integer on 32/64 xp/V/7, but the lack of an Alias could have been the issue. It's recommended that you always use aliases because during the initial change, declaring it without an Alias meant that you wanted 16 bit behavior from the API for backwards compatiblilty. That is a book fact.

    It is funny that both API can do the same sort of thing generally speaking, and sometimes it's best to just check which one works best for the situation.
    Usually I find Async works well with extended keys.

  6. #6
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Windows 7 API Problems

    Also, the preferred method of declaring a Windows API in .NET is using the DllImport attribute, like so;

    vb Code:
    1. <System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint:="GetAsyncKeyState", SetLastError:= True)>  _
    2. Public Shared Function GetAsyncKeyState(ByVal vKey As Integer) As Short
    3. End Function

    As far as I know there isn't any real advantage over the other method, its just that the other method (using Declare like you have done) was just carried over from VB6 as far as I can tell.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  7. #7
    PowerPoster Jenner's Avatar
    Join Date
    Jan 2008
    Location
    Mentor, OH
    Posts
    3,712

    Re: Windows 7 API Problems

    Nope, no difference at all except for looking ugly as sin for pushing HTML style tags into a non-markup based language.
    My CodeBank Submissions: TETRIS using VB.NET2010 and XNA4.0, Strong Encryption Class, Hardware ID Information Class, Generic .NET Data Provider Class, Lambda Function Example, Lat/Long to UTM Conversion Class, Audio Class using BASS.DLL

    Remember to RATE the people who helped you and mark your forum RESOLVED when you're done!

    "Two things are infinite: the universe and human stupidity; and I'm not sure about the universe. "
    - Albert Einstein

  8. #8
    Fanatic Member TTn's Avatar
    Join Date
    Jul 2004
    Posts
    685

    Re: Windows 7 API Problems

    was just carried over from VB6 as far as I can tell.
    Right, and since we are using VB - .NET, both ways could be preferred, depending on how you look at it. Some people get the idea that VBx is wrong because the package says .net on it.

    The old declarations have been fairly consistent over the years, and do have an advantage of being backwards portable.
    For example client wants a simpler program that works regardless of what .NET framework is installed, so a vb6 exe can still be professionally used on Windows 7. The code is very interchangable, and when written in articles it can help frustrated vb6 users, that doubt .net has any offer because they couldn't upgrade their project. I make extensive use of this in my articles, so that vb6 users, can download both zip files, and compare them side by side and learn what most of the common interchanges are. Then they know it's possible, and make the leap.

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Windows 7 API Problems

    There are quite a few things in VB.NET that can be done in two ways: one more like VB6 and one more like C#. If you're an old VB6 developer then you're likely to use the way that's familiar to you but, if you're a new developer then I think the thing to ask yourself is which are you more likely to use in the future: VB6 or C#. For most VB.NET developers, the answer is C#. If for no other reason than consistency, I would recommend taking the more .NET option than the more VB option. Also, while they may not be used all that much, DllImport does provide some advantages over Declare. They are used so little, I can't actually remember what they are off the top of my head, but they are there.

    As for Jenner's comment, attributes are used widely throughout the Framework and in custom classes so the fact that DllImport is an attribute is certainly no reason not to use it.

  10. #10
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Windows 7 API Problems

    Also, while they may not be used all that much, DllImport does provide some advantages over Declare. They are used so little, I can't actually remember what they are off the top of my head, but they are there.
    Well there's all of the options that you can specify in the <DllImport> attribute such as SetLastError, CharSet, CallingConvention etc etc and I'm not sure if all of those are available with the 'old' style declaration.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  11. #11
    Fanatic Member TTn's Avatar
    Join Date
    Jul 2004
    Posts
    685

    Re: Windows 7 API Problems

    CharSet, would be equiv to Auto I believe at least for unicode ansi use.
    Setting the last error can always be done, and I don't think it provides unique behavior. There could be some rare uses in that kind of declaration for sure, but I seldom have found one.
    Besides the the logic to use it in all your declarations just because someone might maybe use it, is somewhat odd and ugly. HTML-like tags should be kept to a minimum, as an exception to the popular rule.

    For most VB.NET developers, the answer is C#.
    Has C# become the most popular recently?
    I knew it was growing, but the last I knew, vb was the most popular, so I don't understand why you conclude that. If someone decides to learn c# along the way, then those declares will be different for a different language, so why add overhead to muddle your code.

  12. #12
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Windows 7 API Problems

    Setting the last error can always be done, and I don't think it provides unique behavior
    Huh? I dont mean manually setting the last error - I mean if you use the SetLastError option in the DllImport attribute then if an API sets the LastError you can access it via the Runtime.InteropServices.Marshal.GetLastWin32Error method

    HTML-like tags should be kept to a minimum, as an exception to the popular rule
    OK firstly...its XML not HTML and XML is heavily used in a lot of modern software including Office 2007 / 2010 and the .NET framework in general. Whenever you use My.Settings you are working with an XML file in the background.
    Secondly... Seriously?? You shouldn't bother writing comments for your methods that provide intellisense text? You shouldn't bother using WCF because that relies on methods and structures being decorated with specific attributes? You shouldn't use the hundreds of attributes that have been put into the .NET framework for a reason? Just because you don't like "HTML-like tags" ... seems a bit daft to me.

    Quote Originally Posted by TTn View Post
    If someone decides to learn c# along the way, then those declares will be different for a different language, so why add overhead to muddle your code.
    No that is the point - they wont be different because C# uses the exact same DllImport attribute... If you go from VB to C# but you were using the old Declare keyword then you would find that did not work in C#, but if you were using DllImport then it would just work.

    Also, I dont think this is about which language is more popular - simply that using features that are common between both of the languages makes sense because then you have less problems if you ever need to do something in C#.
    Last edited by chris128; Jul 12th, 2010 at 10:46 AM.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  13. #13
    Fanatic Member TTn's Avatar
    Join Date
    Jul 2004
    Posts
    685

    Re: Windows 7 API Problems

    Go over to the C# forum and preach it then.

    MSDN
    MSDN: The most common way to call Windows APIs is via the Declare statement.

    Done.

  14. #14
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: [RESOLVED] Windows 7 API Problems

    Nice thorough answer to all of the points I raised there... well done
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  15. #15
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: Windows 7 API Problems

    Quote Originally Posted by TTn View Post
    Go over to the C# forum and preach it then.
    Done.
    You've missed my point. It had nothing to do with what language is most popular. I'm talking about new VB.NET developers. Some will stick solely with VB.NET and some will learn other languages, either instead of VB.NET or as well. Some will learn VB6, some will learn C#, some will learn other .NET languages and some will learn other non-.NET languages. Of those, I'm sure that more will learn C# than VB6, so it makes more sense to write VB.NET code more like C# code than like VB6 code for the majority of new VB.NET developers. You gain nothing by using VB6 holdovers.

  16. #16
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Windows 7 API Problems

    Quote Originally Posted by TTn View Post
    Go over to the C# forum and preach it then.

    MSDN



    Done.
    lol yes of course its the most common because anyone coming from VB6 will be using that because that is what they are used too...
    Plus I like how you neglected to include this quote from the same MSDN article:
    DllImport is roughly equivalent to using a Declare statement but provides more control over how functions are called
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  17. #17
    Fanatic Member TTn's Avatar
    Join Date
    Jul 2004
    Posts
    685

    Re: [RESOLVED] Windows 7 API Problems

    Plus I like how you neglected to include this quote from the same MSDN article:
    You are being adversarial for no reason.
    I've have acknowledged the slight advantage, and that we rarely seem to use them.
    There could be some rare uses in that kind of declaration for sure, but I seldom have found one.
    I say we, because jmcilhinney appears to agree with the rarity of use in vb.
    If there were more vb/c# developers, then it would have a distinct advantage of inter-language compatibility, and would be preferred for vb.net.

    The point was:
    jmcilhinney, mentioned his opinion as if it were more factual:
    For most VB.NET developers, the answer is C#.{>50%}
    I get it, new developers can do what you want, but it's nice to be clear to others of your reasoning for using the import with vb.
    It's alot of extra overhead for some to learn, when from their perspective it isn't even needed.
    In my two libraries, I use two different styles, for the two languages, and more people like to see it that way.

    We are speaking on topic to the same new/old audience here in a vb forum, and the greater portion of the audience uses, and prefers the declare.

  18. #18
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,344

    Re: [RESOLVED] Windows 7 API Problems

    Quote Originally Posted by TTn View Post
    the greater portion of the audience uses, and prefers the declare.
    I don't necessarily agree with that. Uses? Maybe. Prefers? I don't know but actually doubt it. I see a VERY large number of people write VB.NET code like VB6 simply because they were taught by someone who has themselves coded in VB6. I see many, many rank beginners doing things like using Randomize and Rnd to generate random numbers when the Random class is clearly superior. The fact that people do something one way is not necessarily an indication of preference, but quite possibly and indication that no-one has shown them that another option exists.

  19. #19
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: [RESOLVED] Windows 7 API Problems

    I just dont get why anyone after reading the points that JMC and myself have mentioned here would still want to use Declare... You have absolutely nothing to loose by using DllImport, yet there are several benefits. Who cares if you don't regularly use those benefits, the fact that there are any benefits at all surely means that it is a good idea to get into the habit of always using DllImport rather than use Declare most of the time but then use DllImport if you have to.

    According to MSDN the Declare keyword "emits" the DllImport attribute anyway, so you are still using the same thing behind the scenes but you are just etting yourself used to a different syntax that hides some of the capabilities from you.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  20. #20
    Fanatic Member TTn's Avatar
    Join Date
    Jul 2004
    Posts
    685

    Re: [RESOLVED] Windows 7 API Problems

    You have absolutely nothing to loose by using DllImport,
    Now you missed my points. Things to loose.
    A. 16-bit backwards portability without an Alias.
    B. Vbx backwards portability, or learning interchange towards .net for doubters.
    C. Easier and more elegant to read for all team members, and readers in general.
    Vb is more of a human/computer language, and should remain that way, especially for layman, or investors that can't understand C#, but need to look though the developers work. This is a professional tip.
    D. Less line spaces, so code is shorter and easier to scroll through. More signifigant in larger projects, which matters to me.
    E. No extra overhead to learn the different options, for existing vbers. Newcomers, most of which will not use the options will also save overhead.
    F. No need to habit and repeat something(O.C.D), you will rarely if ever use.
    When I use my hair brush, I have it in my hand, but I don't hold it evertime I go into the bathroom. Code isn't a place to ritualize, when it's an exception to the rule. This keeps inline with the intent of vb, which is RAD(rapid application development).


    Things to gain:
    A. If you plan on using C# now or future, imports will be interchangable, across languages. Not really signifigant or time saving for most, but true.
    B. If you will be frequently using the rare options. Could be highly signifigant to a few.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width