{"id":37173,"date":"2004-11-30T07:00:00","date_gmt":"2004-11-30T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2004\/11\/30\/whats-the-difference-between-getkeystate-and-getasynckeystate\/"},"modified":"2004-11-30T07:00:00","modified_gmt":"2004-11-30T07:00:00","slug":"whats-the-difference-between-getkeystate-and-getasynckeystate","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20041130-00\/?p=37173","title":{"rendered":"What&#8217;s the difference between GetKeyState and GetAsyncKeyState?"},"content":{"rendered":"<p>I&#8217;ve seen some confusion over the difference between <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/userinput\/keyboardinput\/keyboardinputreference\/keyboardinputfunctions\/getkeystate.asp\"> the <code>GetKeyState<\/code> function<\/a> and <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/winui\/windowsuserinterface\/userinput\/keyboardinput\/keyboardinputreference\/keyboardinputfunctions\/getasynckeystate.asp\"> the <code>GetAsyncKeyState<\/code> function<\/a>.<\/p>\n<p> <code>GetKeyState<\/code> returns the virtual key state. In other words, <code>GetKeyState<\/code> reports the state of the keyboard <b>based on the messages you have retrieved from your input queue<\/b>. This is not the same as the physical keyboard state: <\/p>\n<ul>\n<li>  If the user has typed ahead, <code>GetKeyState<\/code> doesn&#8217;t report those changes until you use <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/Windowing\/MessagesandMessageQueues\/MessagesandMessageQueuesReference\/MessagesandMessageQueuesFunctions\/PeekMessage.asp\"> the <code>PeekMessage<\/code> function<\/a> or <a href=\"http:\/\/msdn.microsoft.com\/library\/en-us\/winui\/WinUI\/WindowsUserInterface\/Windowing\/MessagesandMessageQueues\/MessagesandMessageQueuesReference\/MessagesandMessageQueuesFunctions\/GetMessage.asp\"> the <code>GetMessage<\/code> function<\/a> to retrieve the message from your input queue. <\/p>\n<\/li>\n<li>\n<p> If the user has switched to another program, then the <code>GetKeyState<\/code> function will not see the input that the user typed into that other program, since that input was not sent to your input queue. <\/p>\n<\/li>\n<\/ul>\n<p> When should you use <code>GetKeyState<\/code> and when should you use <code>GetAsyncKeyState<\/code>? <\/p>\n<p> For user interface work, you nearly always want <code>GetKeyState<\/code>. <\/p>\n<p> If you are responding to an input message and want to know what keys were pressed at the time that input was generated, then you want to use <code>GetKeyState<\/code>. For example, if you want to distinguish a left-click of the mouse from an Alt+LeftClick, you must use <code>GetKeyState<\/code> to query the state of the Alt key (known as VK_MENU for historical reasons). That&#8217;s because you want to know whether the Alt key was down <b>when the user clicked the mouse<\/b>, not whether the key is down <b>this very instant<\/b>. Whether the user released the Alt key between the time they clicked and the time you processed the message is irrelevant.  You care that the Alt key was down at the time of the click. <\/p>\n<p> Note that if you are implementing a context menu handler, then you shouldn&#8217;t be using either <code>GetKeyState<\/code> or <code>GetAsyncKeyState<\/code>, because the context menu can be invoked programmatically without any user action. For <code>IContextMenu::QueryContextMenu<\/code>, you should test for the <code>CMF_EXTENDEDVERBS<\/code> flag to detect whether you should display extended commands rather than querying the keyboard directly. Similarly, for <code>IContextMenu::InvokeCommand<\/code>, <a href=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2004\/09\/24\/234113.aspx\"> you should be testing the <code>CMIC_MASK_CONTROL_DOWN<\/code> and <code>CMIC_MASK_SHIFT_DOWN<\/code> flags<\/a> if you want to alter your behavior based on the shift states. <\/p>\n<p> Given this primer on the difference between  <code>GetKeyState<\/code> and <code>GetAsyncKeyState<\/code>, you can now <a href=\"http:\/\/groups.google.com\/groups?selm=ubDbObcSEHA.504@TK2MSFTNGP11.phx.gbl\"> explain the behavior this user is seeing<\/a>. <\/p>\n<p> [Updated: 1 Dec 2004, minor typo.] <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve seen some confusion over the difference between the GetKeyState function and the GetAsyncKeyState function. GetKeyState returns the virtual key state. In other words, GetKeyState reports the state of the keyboard based on the messages you have retrieved from your input queue. This is not the same as the physical keyboard state: If the user [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-37173","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>I&#8217;ve seen some confusion over the difference between the GetKeyState function and the GetAsyncKeyState function. GetKeyState returns the virtual key state. In other words, GetKeyState reports the state of the keyboard based on the messages you have retrieved from your input queue. This is not the same as the physical keyboard state: If the user [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=37173"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/37173\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=37173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=37173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=37173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}