void
winCreateWindowsWindow (WindowPtr pWin)
{
  int                   iX, iY;
  int			iWidth;
  int			iHeight;
  HWND			hWnd;
  WNDCLASSEX		wc;
  winWindowPriv(pWin);
  HICON			hIcon;
  HICON			hIconSmall;
#define CLASS_NAME_LENGTH 512
  char                  pszClass[CLASS_NAME_LENGTH], pszWindowID[12];
  char                  *res_name, *res_class, *res_role;
  static int		s_iWindowID = 0;
  winPrivScreenPtr	pScreenPriv = pWinPriv->pScreenPriv;
  WinXSizeHints         hints;

#if CYGMULTIWINDOW_DEBUG
  ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin);
#endif

  iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
  iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);

  /* Default positions if none specified */
  if (!winMultiWindowGetWMNormalHints(pWin, &hints))
    hints.flags = 0;
  if ( !(hints.flags & (USPosition|PPosition)) &&
       !winMultiWindowGetTransientFor (pWin, NULL) &&
       !pWin->overrideRedirect )
    {
      iX = CW_USEDEFAULT;
      iY = CW_USEDEFAULT;
    }

  iWidth = pWin->drawable.width;
  iHeight = pWin->drawable.height;

  winSelectIcons(pWin, &hIcon, &hIconSmall); 

  /* Set standard class name prefix so we can identify window easily */
  strncpy (pszClass, WINDOW_CLASS_X, sizeof(pszClass));

  if (winMultiWindowGetClassHint (pWin, &res_name, &res_class))
    {
      strncat (pszClass, "-", 1);
      strncat (pszClass, res_name, CLASS_NAME_LENGTH - strlen (pszClass));
      strncat (pszClass, "-", 1);
      strncat (pszClass, res_class, CLASS_NAME_LENGTH - strlen (pszClass));
      
      /* Check if a window class is provided by the WM_WINDOW_ROLE property,
       * if not use the WM_CLASS information.
       * For further information see:
       * http://tronche.com/gui/x/icccm/sec-5.html
       */ 
      if (winMultiWindowGetWindowRole (pWin, &res_role) )
	{
	  strcat (pszClass, "-");
	  strcat (pszClass, res_role);
	  free (res_role);
	}

      free (res_name);
      free (res_class);
    }

  /* Add incrementing window ID to make unique class name */
  snprintf (pszWindowID, sizeof(pszWindowID), "-%x", s_iWindowID++);
  pszWindowID[sizeof(pszWindowID)-1] = 0;
  strcat (pszClass, pszWindowID);

#if CYGMULTIWINDOW_DEBUG
  ErrorF ("winCreateWindowsWindow - Creating class: %s\n", pszClass);
#endif

  /* Setup our window class */
  wc.cbSize = sizeof(wc);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = winTopLevelWindowProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = g_hInstance;
  wc.hIcon = hIcon;
  wc.hIconSm = hIconSmall;
  wc.hCursor = 0;
  wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = pszClass;
  RegisterClassEx (&wc);

  /* Create the window */
  /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
  /* CW_USEDEFAULT, change back to popup after creation */
  hWnd = CreateWindowExA (WS_EX_TOOLWINDOW,	/* Extended styles */
			  pszClass,		/* Class name */
			  WINDOW_TITLE_X,	/* Window name */
			  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
			  iX,			/* Horizontal position */
			  iY,			/* Vertical position */
			  iWidth,		/* Right edge */ 
			  iHeight,		/* Bottom edge */
			  (HWND) NULL,		/* No parent or owner window */
			  (HMENU) NULL,		/* No menu */
			  GetModuleHandle (NULL), /* Instance handle */
			  pWin);		/* ScreenPrivates */
  if (hWnd == NULL)
    {
      ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
	      (int) GetLastError ());
    }
 
  /* Change style back to popup, already placed... */
  SetWindowLong (hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
  SetWindowPos (hWnd, 0, 0, 0, 0, 0,
		SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  /* Make sure it gets the proper system menu for a WS_POPUP, too */
  GetSystemMenu (hWnd, TRUE);

  pWinPriv->hWnd = hWnd;

  /* Cause any .XWinrc menus to be added in main WNDPROC */
  PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
  
  SetProp (pWinPriv->hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));

  /* Flag that this Windows window handles its own activation */
  SetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);

  /* Call engine-specific create window procedure */
  (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
}
Ejemplo n.º 2
0
/*
 * ValidateSizing - Ensures size request respects hints
 */
static int
ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
{
    WinXSizeHints sizeHints;
    RECT *rect;
    int iWidth, iHeight, iTopBorder;
    POINT pt;

    /* Invalid input checking */
    if (pWin == NULL || lParam == 0) {
        ErrorF("Invalid input checking\n");
        return FALSE;
    }

    /* No size hints, no checking */
    if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints)) {
        ErrorF("No size hints, no checking\n");
        return FALSE;
    }

    /* Avoid divide-by-zero */
    if (sizeHints.flags & PResizeInc) {
        if (sizeHints.width_inc == 0)
            sizeHints.width_inc = 1;
        if (sizeHints.height_inc == 0)
            sizeHints.height_inc = 1;
    }

    rect = (RECT *) lParam;

    iWidth = rect->right - rect->left;
    iHeight = rect->bottom - rect->top;

    /* Get title bar height, there must be an easier way?! */
    pt.x = pt.y = 0;
    ClientToScreen(hwnd, &pt);
    iTopBorder = pt.y - rect->top;

    /* Now remove size of any borders */
    iWidth -= 2 * GetSystemMetrics(SM_CXSIZEFRAME);
    iHeight -= GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;

    /* Constrain the size to legal values */
    ConstrainSize(sizeHints, &iWidth, &iHeight);

    /* Add back the borders */
    iWidth += 2 * GetSystemMetrics(SM_CXSIZEFRAME);
    iHeight += GetSystemMetrics(SM_CYSIZEFRAME) + iTopBorder;

    /* Adjust size according to where we're dragging from */
    switch (wParam) {
    case WMSZ_TOP:
    case WMSZ_TOPRIGHT:
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_RIGHT:
        rect->right = rect->left + iWidth;
        break;
    default:
        rect->left = rect->right - iWidth;
        break;
    }
    switch (wParam) {
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_BOTTOMLEFT:
    case WMSZ_RIGHT:
    case WMSZ_LEFT:
        rect->bottom = rect->top + iHeight;
        break;
    default:
        rect->top = rect->bottom - iHeight;
        break;
    }
    return TRUE;
}
Ejemplo n.º 3
0
/*
 * ValidateSizing - Ensures size request respects hints
 */
static int
ValidateSizing(HWND hwnd, WindowPtr pWin, WPARAM wParam, LPARAM lParam)
{
    WinXSizeHints sizeHints;
    RECT *rect;
    int iWidth, iHeight;
    RECT rcClient, rcWindow;
    int iBorderWidthX, iBorderWidthY;

    /* Invalid input checking */
    if (pWin == NULL || lParam == 0)
        return FALSE;

    /* No size hints, no checking */
    if (!winMultiWindowGetWMNormalHints(pWin, &sizeHints))
        return FALSE;

    /* Avoid divide-by-zero */
    if (sizeHints.flags & PResizeInc) {
        if (sizeHints.width_inc == 0)
            sizeHints.width_inc = 1;
        if (sizeHints.height_inc == 0)
            sizeHints.height_inc = 1;
    }

    rect = (RECT *) lParam;

    iWidth = rect->right - rect->left;
    iHeight = rect->bottom - rect->top;

    /* Now remove size of any borders and title bar */
    GetClientRect(hwnd, &rcClient);
    GetWindowRect(hwnd, &rcWindow);
    iBorderWidthX =
        (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
    iBorderWidthY =
        (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
    iWidth -= iBorderWidthX;
    iHeight -= iBorderWidthY;

    /* Constrain the size to legal values */
    ConstrainSize(sizeHints, &iWidth, &iHeight);

    /* Add back the size of borders and title bar */
    iWidth += iBorderWidthX;
    iHeight += iBorderWidthY;

    /* Adjust size according to where we're dragging from */
    switch (wParam) {
    case WMSZ_TOP:
    case WMSZ_TOPRIGHT:
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_RIGHT:
        rect->right = rect->left + iWidth;
        break;
    default:
        rect->left = rect->right - iWidth;
        break;
    }
    switch (wParam) {
    case WMSZ_BOTTOM:
    case WMSZ_BOTTOMRIGHT:
    case WMSZ_BOTTOMLEFT:
    case WMSZ_RIGHT:
    case WMSZ_LEFT:
        rect->bottom = rect->top + iHeight;
        break;
    default:
        rect->top = rect->bottom - iHeight;
        break;
    }
    return TRUE;
}