Esempio n. 1
0
static Ihandle* winContainerWmCommandGetIhandle(Ihandle *ih, WPARAM wp, LPARAM lp)
{
  /* WPARAM - if HIWORD is 0 if the message is from a menu.
              or HIWORD is 1 if the message is from an accelerator.
              or HIWORD is the notification code if the message is from a control.
              LOWORD is the identifier.
     LPARAM - the control sending the message or 0. */

  Ihandle *child = NULL;

  if (HIWORD(wp)==0 && lp==0 && LOWORD(wp)>10)
  {
    Ihandle* dlg_menu = IupGetAttributeHandle(ih, "MENU");
    if (dlg_menu)
      child = iupwinMenuGetItemHandle((HMENU)dlg_menu->handle, LOWORD(wp));  /* menu */
  }
  else 
  {
    if (lp==0)
      child = ih;                              /* native parent */
    else
    {
      child = iupwinHandleGet((HWND)lp);       /* control */
      if (!child)
        child = iupwinHandleGet(GetParent((HWND)lp));       /* control */
    }
  }

  return child;
}
Esempio n. 2
0
int iupdrvMenuPopup(Ihandle* ih, int x, int y)
{
  HWND hWndActive = GetActiveWindow();
  int tray_menu = 0;
  int menuId;

  if (!hWndActive)
  {
    /* search for a valid handle */
    Ihandle* dlg = iupDlgListFirst();
    do 
    {
      if (dlg->handle)
      {
        hWndActive = dlg->handle;  /* found a valid handle */

        /* if not a "TRAY" dialog, keep searching, because TRAY is a special case */
        if (iupAttribGetBoolean(dlg, "TRAY")) 
          break;
      }
      dlg = iupDlgListNext();
    } while (dlg);
  }

  /* Necessary to avoid tray dialogs to lock popup menus (they get sticky after the 1st time) */
  if (hWndActive)
  {
    Ihandle* dlg = iupwinHandleGet(hWndActive);
    if (dlg && iupAttribGetBoolean(dlg, "TRAY"))
    {
      /* To display a context menu for a notification icon, 
         the current window must be the foreground window. */
      SetForegroundWindow(hWndActive);
      tray_menu = 1;
    }
  }

  /* stop processing here. messages will not go to the message loop */
  menuId = TrackPopupMenu((HMENU)ih->handle, TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, x, y, 0, hWndActive, NULL);

  if (tray_menu)
  {
    /* You must force a task switch to the application that 
       called TrackPopupMenu at some time in the near future. 
       This is done by posting a benign message to the window. */
    PostMessage(hWndActive, WM_NULL, 0, 0);
  }

  if (menuId)
  {
    Icallback cb;
    Ihandle* ih_item = iupwinMenuGetItemHandle((HMENU)ih->handle, menuId);
    if (!ih_item) return IUP_NOERROR;

    winItemCheckToggle(ih_item);

    cb = IupGetCallback(ih_item, "ACTION");
    if (cb && cb(ih_item) == IUP_CLOSE)
      IupExitLoop();
  }

  return IUP_NOERROR;
}
Esempio n. 3
0
void iupwinMenuDialogProc(Ihandle* ih_dialog, UINT msg, WPARAM wp, LPARAM lp)
{
  /* called only from winDialogBaseProc */

  switch (msg)
  {
  case WM_INITMENUPOPUP:
    {
      HMENU hMenu = (HMENU)wp;
      Ihandle *ih = iupwinMenuGetHandle(hMenu);
      if (ih)
      {
        Icallback cb = (Icallback)IupGetCallback(ih, "OPEN_CB");
        if (!cb && ih->parent) cb = (Icallback)IupGetCallback(ih->parent, "OPEN_CB");  /* check also in the Submenu */
        if (cb) cb(ih);
      }
      break;
    }
  case WM_UNINITMENUPOPUP:
    {
      HMENU hMenu = (HMENU)wp;
      Ihandle *ih = iupwinMenuGetHandle(hMenu);
      if (ih)
      {
        Icallback cb = (Icallback)IupGetCallback(ih, "MENUCLOSE_CB");
        if (!cb && ih->parent) cb = (Icallback)IupGetCallback(ih->parent, "MENUCLOSE_CB");  /* check also in the Submenu */
        if (cb) cb(ih);
      }
      break;
    }
  case WM_MENUSELECT:
    {
      HMENU hMenu = (HMENU)lp;
      Ihandle *ih;

      if (!lp)
        break;

      if ((HIWORD(wp) & MF_POPUP) || (HIWORD(wp) & MF_SYSMENU)) /* drop-down ih or submenu. */
      {
        UINT menuindex = LOWORD(wp);
        HMENU hsubmenu = GetSubMenu(hMenu, menuindex);
        ih = iupwinMenuGetHandle(hsubmenu);  /* returns the handle of a IupMenu */
        if (ih) ih = ih->parent;  /* gets the submenu */
      }
      else /* ih item */
      {
        UINT menuID = LOWORD(wp);
        ih = iupwinMenuGetItemHandle(hMenu, menuID);
      }

      if (ih)
      {
        Icallback cb = IupGetCallback(ih, "HIGHLIGHT_CB");
        if (cb) cb(ih);
      }
      break;
    }
  case WM_MENUCOMMAND:
    {
      int menuId = GetMenuItemID((HMENU)lp, (int)wp);
      Icallback cb;
      Ihandle* ih;
        
      if (menuId >= IUP_MDI_FIRSTCHILD)
        break;
        
      ih  = iupwinMenuGetItemHandle((HMENU)lp, menuId);
      if (!ih)
        break;

      winItemCheckToggle(ih);

      cb = IupGetCallback(ih, "ACTION");
      if (cb && cb(ih) == IUP_CLOSE)
        IupExitLoop();

      break;
    }
  case WM_ENTERMENULOOP:
    {
      /* Simulate WM_KILLFOCUS when the menu interaction is started */
      Ihandle* lastfocus = (Ihandle*)iupAttribGet(ih_dialog, "_IUPWIN_LASTFOCUS");
      if (lastfocus) iupCallKillFocusCb(lastfocus);
      break;
    }
  case WM_EXITMENULOOP:
    {
      /* Simulate WM_GETFOCUS when the menu interaction is stopped */
      Ihandle* lastfocus = (Ihandle*)iupAttribGet(ih_dialog, "_IUPWIN_LASTFOCUS");
      if (lastfocus) iupCallGetFocusCb(lastfocus);
      break;
    }
  }
}
Esempio n. 4
0
int iupwinBaseContainerMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
{
  /* All messages here are sent to the parent Window, 
     but they are usefull for child controls.  */

  switch (msg)
  {
  case WM_COMMAND:
    {
      Ihandle* child = winContainerWmCommandGetIhandle(ih, wp, lp);
      if (child)
      {
        IFwmCommand cb = (IFwmCommand)IupGetCallback(child, "_IUPWIN_COMMAND_CB");
        if (cb)
          cb(child, wp, lp);
      }

      break;
    }
  case WM_CTLCOLOREDIT:
  case WM_CTLCOLORLISTBOX:
  case WM_CTLCOLORBTN:
  case WM_CTLCOLORSCROLLBAR:
  case WM_CTLCOLORSTATIC:
    {
      Ihandle* child = iupwinHandleGet((HWND)lp);
      if (child && winCheckParent(child, ih))
      {
        IFctlColor cb = (IFctlColor)IupGetCallback(child, "_IUPWIN_CTLCOLOR_CB");
        if (cb)
          return cb(child, (HDC)wp, result);
      }
      break;
    }
  case WM_DRAWITEM:   /* for OWNERDRAW controls */
    {
      Ihandle *child;
      DRAWITEMSTRUCT *drawitem = (LPDRAWITEMSTRUCT)lp;
      if (!drawitem)
        break;

      if (wp == 0) /* a menu */
        child = iupwinMenuGetItemHandle((HMENU)drawitem->hwndItem, drawitem->itemID);
      else
      {
        child = iupwinHandleGet(drawitem->hwndItem); 
        if (child && !winCheckParent(child, ih))
          child = NULL;
      }

      if (child)
      {
        IFdrawItem cb = (IFdrawItem)IupGetCallback(child, "_IUPWIN_DRAWITEM_CB");
        if (cb) 
        {
          cb(child, (void*)drawitem);
          *result = TRUE;
          return 1;
        }
      }
      break;
    }
  case WM_HSCROLL:
  case WM_VSCROLL:
    {
      Ihandle *child = iupwinHandleGet((HWND)lp);
      if (child && winCheckParent(child, ih))
      {
        IFni cb = (IFni)IupGetCallback(child, "_IUPWIN_CUSTOMSCROLL_CB");
        if (cb)
          cb(child, LOWORD(wp));
      }
      break;
    }
  case WM_NOTIFY:   /* Currently, the following controls support custom draw functionality: 
                       Header, List-view, Rebar, Toolbar, ToolTip, Trackbar, Tree-view.
                       And for Button if using Windows XP Style. */
    {
      Ihandle *child;
      NMHDR* msg_info = (NMHDR*)lp;
      if (!msg_info)
        break;

      child = iupwinHandleGet(msg_info->hwndFrom);
      if (child && winCheckParent(child, ih))
      {
        IFnotify cb = (IFnotify)IupGetCallback(child, "_IUPWIN_NOTIFY_CB");
        if (cb)
        {
          int ret;
          if (cb(child, (void*)msg_info, &ret))
          {
            *result = (LRESULT)ret;
            return 1;
          }
        }
      }

      break;
    }
  default:
    {
      /* sent to the list parent */
      if (msg == WM_DRAGLISTMSG)
      {
        DRAGLISTINFO* lpDrag = (DRAGLISTINFO*) lp;
        Ihandle *child = iupwinHandleGet(lpDrag->hWnd);
        if (child && winCheckParent(child, ih))
        {
          *result = iupwinListDND(child, lpDrag->uNotification, lpDrag->ptCursor);
          return 1;
        }
      }
      break;
    }
  }

  return iupwinBaseMsgProc(ih, msg, wp, lp, result);
}
Esempio n. 5
0
int iupwinBaseMsgProc(Ihandle* ih, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result)
{ 
  switch (msg)
  {
  case WM_INPUTLANGCHANGE:
    iupwinKeyInit();
    break;
  case WM_GETDLGCODE:
    {
      *result = DLGC_WANTALLKEYS;
      return 1;
    }
  case WM_NOTIFY: /* usually sent only to parent,               */
    {             /* but TIPs are configured to be handled here */
      NMHDR* msg_info = (NMHDR*)lp;
      if (msg_info->code == TTN_GETDISPINFO)
        iupwinTipsGetDispInfo(lp);
      break;
    }
  case WM_DROPFILES:
    iupwinDropFiles((HDROP)wp, ih);
    break;
  case WM_LBUTTONDOWN:
    if(iupAttribGetBoolean(ih, "DRAGSOURCE"))
    {
      if (iupwinDragStart(ih))
      {
        *result = 0;
        return 1;  /* abort default processing */
      }
    }
    break;
  case WM_HELP:
    {
      Ihandle* child;
      HELPINFO* help_info = (HELPINFO*)lp;

      if (help_info->iContextType == HELPINFO_MENUITEM)
        child = iupwinMenuGetItemHandle((HMENU)help_info->hItemHandle, (int)help_info->iCtrlId);
      else
        child = iupwinHandleGet((HWND)help_info->hItemHandle);

      if (child)
      {
        Icallback cb = (Icallback) IupGetCallback(child, "HELP_CB");
        if (cb) 
        {
          if (cb(child) == IUP_CLOSE) 
            IupExitLoop();

          *result = 0;
          return 1;  /* abort default processing */
        }
      }
      break;
    }
  case WM_MOUSELEAVE:
    {
      Icallback leave_cb = IupGetCallback(ih, "LEAVEWINDOW_CB");
      if (leave_cb)
        leave_cb(ih);

      iupAttribSet(ih, "_IUPWIN_ENTERWIN", NULL);  /* enable tracking again */
      break;
    }
  case WM_MOUSEHOVER:
    {
      Icallback enter_cb = IupGetCallback(ih, "ENTERWINDOW_CB");
      if (enter_cb)
        enter_cb(ih);
      break;
    }
  case WM_MOUSEMOVE:
    {
      /* set tracking only once, but only until track message is processed. */
      if (!iupAttribGet(ih, "_IUPWIN_ENTERWIN"))
      {
        /* set tracking only if enter or leave callbacks are defined */
        Icallback enter_cb = IupGetCallback(ih, "ENTERWINDOW_CB");
        Icallback leave_cb = IupGetCallback(ih, "LEAVEWINDOW_CB");
        if (enter_cb || leave_cb)
        {
          /* must be called so WM_MOUSEHOVER and WM_MOUSELEAVE will be called */
          winTrackMouseHoverLeave(ih);

          iupAttribSet(ih, "_IUPWIN_ENTERWIN", "1");
        }
      }
      break;
    }
  case WM_KEYDOWN:
  case WM_SYSKEYDOWN:
    if (!iupwinKeyEvent(ih, (int)wp, 1))
    {
      *result = 0;
      return 1;   /* abort default processing */
    }
    break;
  case WM_SYSKEYUP:
  case WM_KEYUP:
    {
      int ret;
      if (wp == VK_SNAPSHOT) /* called only on key up */
      {
        ret = iupwinKeyEvent(ih, (int)wp, 1);
        if (ret && iupObjectCheck(ih))
          ret = iupwinKeyEvent(ih, (int)wp, 0);
      }
      else
        ret = iupwinKeyEvent(ih, (int)wp, 0);

      if (!ret)
      {
        *result = 0;
        return 1;  /* abort default processing */
      }

      break;
    }
  case WM_SETFOCUS:
    /* TODO: Not setting WS_TABSTOP still allows the control 
       to receive the focus when clicked. 
       But this code does make several controls 
       with CANFOCUS=NO to stop working. 
       So we use it inside some of the controls. */
/*  if (!iupAttribGetBoolean(ih, "CANFOCUS"))
    {
      HWND previous = (HWND)wp;
      if (previous && previous != ih->handle)
        SetFocus(previous);
      break;
    }  */
    iupwinWmSetFocus(ih);
    break;
  case WM_KILLFOCUS:
    iupCallKillFocusCb(ih);
    break;
  case WM_SETCURSOR: 
    { 
      if (ih->handle == (HWND)wp && LOWORD(lp)==HTCLIENT)
      {
        HCURSOR hCur = (HCURSOR)iupAttribGet(ih, "_IUPWIN_HCURSOR");
        if (hCur)
        {
          SetCursor(hCur); 
          *result = 1;
          return 1;
        }
        else if (iupAttribGet(ih, "CURSOR"))
        {
          SetCursor(NULL); 
          *result = 1;
          return 1;
        }
      }
      break; 
    } 
  case WM_TOUCH:
    /* TODO: 
     - considering touch messages are greedy, one window got it all?
     - how this work? only for the dialog, or also for the children?
     - should a container forward to its children?
    */
    if (LOWORD(wp))
      iupwinTouchProcessInput(ih, (int)LOWORD(wp), (void*)lp);
    break;
  case WOM_CLOSE:
  case WOM_DONE:
  case WOM_OPEN:
    {
      IFni cb = (IFni)IupGetCallback(ih, "WOM_CB");
      if (cb)
      {
        int v = -2; /* Error */
        switch(msg)
        {
        case WOM_OPEN:  v = 1;  break;
        case WOM_DONE:  v = 0;  break;
        case WOM_CLOSE: v = -1; break;
        }
        cb(ih, v);
      }
      break;
    }
  }

  return 0;
}