summaryrefslogtreecommitdiff
path: root/iup/src/win/iupwin_focus.c
blob: 63da02d33b5299f6beae665a0d305393f7727bfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/** \file
 * \brief Windows Focus
 *
 * See Copyright Notice in "iup.h"
 */

#include <stdlib.h>
#include <stdio.h>

#include <windows.h>

#include "iup.h"
#include "iup_object.h"
#include "iup_focus.h"
#include "iup_assert.h" 
#include "iup_drv.h" 
#include "iup_attrib.h" 

#include "iupwin_drv.h"
#include "iupwin_handle.h"

/* not defined for gcc */
#ifndef WM_CHANGEUISTATE
#define WM_CHANGEUISTATE                0x0127
#endif
#ifndef UIS_CLEAR
#define UIS_CLEAR                       2
#endif
#ifndef UISF_HIDEFOCUS
#define UISF_HIDEFOCUS                  0x1
#endif

/* Since Windows XP, the focus feedback only appears after the user press a key.
   Except for the IupText where the feedback is the caret.
   Before that if you click in a control the focus feedback will be hidden.

   We manually send WM_CHANGEUISTATE because we do not use IsDialogMessage anymore,
   and the focus feedback was not shown even after the used press a key.

   TODO: I would like a form to always show the feedback, but could not understand how WM_CHANGEUISTATE works.
         Neither SystemParametersInfo(SPI_SETKEYBOARDCUES, TRUE) or SystemParametersInfo(SPI_SETKEYBOARDPREF, TRUE) worked.
*/
void iupdrvSetFocus(Ihandle *ih)
{
  SetFocus(ih->handle);
  SendMessage(ih->handle, WM_CHANGEUISTATE, UIS_CLEAR|UISF_HIDEFOCUS, 0);
}

void iupwinWmSetFocus(Ihandle *ih)
{
  Ihandle* dialog = IupGetDialog(ih);
  if (ih != dialog)
    iupAttribSetStr(dialog, "_IUPWIN_LASTFOCUS", (char*)ih);  /* used by IupMenu */
  else
  {
    /* if a control inside that dialog had the focus, then reset to it when the dialog gets the focus */
    Ihandle* lastfocus = (Ihandle*)iupAttribGet(dialog, "_IUPWIN_LASTFOCUS");
    if (lastfocus) IupSetFocus(lastfocus);
  }

  iupCallGetFocusCb(ih);
}