Esempio n. 1
0
/* adjust windows to fit main window layout
   ---------------------------
   |        Status           |
   +-------------------------+
   |                         |
   |                         |
   |          MAP            |
   |                         |
   |                         |
   +-------------------------+
   |      Command pad        |
   +-------------------------+
   |        Messages         |
   ---------------------------
*/
void
mswin_layout_main_window(HWND changed_child)
{
    winid i;
    RECT client_rt, wnd_rect;
    POINT status_org;
    SIZE status_size;
    POINT msg_org;
    SIZE msg_size;
    POINT map_org;
    SIZE map_size;
    POINT cmd_org;
    SIZE cmd_size;
    HWND wnd_status, wnd_msg;
    PNHMainWindow data;
#if defined(WIN_CE_POCKETPC)
    SIPINFO sip;
    RECT menu_bar;
    RECT visible_rt;
    POINT pt;
#endif

    GetClientRect(GetNHApp()->hMainWnd, &client_rt);

#if defined(WIN_CE_POCKETPC)
    ZeroMemory(&sip, sizeof(sip));
    sip.cbSize = sizeof(sip);
    SHSipInfo(SPI_GETSIPINFO, 0, &sip, 0);
    if (GetNHApp()->bFullScreen)
        sip.rcVisibleDesktop.top = 0;

    /* adjust client rectangle size */
    GetWindowRect(GetNHApp()->hMenuBar, &menu_bar);
    client_rt.bottom -= menu_bar.bottom - menu_bar.top;

    /* calcuate visible rect in client coordinates */
    pt.x = sip.rcVisibleDesktop.left;
    pt.y = sip.rcVisibleDesktop.top;
    ScreenToClient(GetNHApp()->hMainWnd, &pt);
    SetRect(&wnd_rect, pt.x, pt.y,
            pt.x + sip.rcVisibleDesktop.right - sip.rcVisibleDesktop.left,
            pt.y + sip.rcVisibleDesktop.bottom - sip.rcVisibleDesktop.top);
    IntersectRect(&visible_rt, &client_rt, &wnd_rect);
#else
#if !defined(WIN_CE_SMARTPHONE)
    client_rt.top += CommandBar_Height(GetNHApp()->hMenuBar);
#else
    /* Smartphone only */
    if (GetNHApp()->bFullScreen) {
        RECT menu_bar;
        GetWindowRect(GetNHApp()->hMenuBar, &menu_bar);
        client_rt.bottom -= menu_bar.bottom - menu_bar.top;
    }
#endif
#endif

    /* get window data */
    data = (PNHMainWindow) GetWindowLong(GetNHApp()->hMainWnd, GWL_USERDATA);

    /* get sizes of child windows */
    wnd_status = mswin_hwnd_from_winid(WIN_STATUS);
    if (IsWindow(wnd_status)) {
        mswin_status_window_size(wnd_status, &status_size);
    } else {
        status_size.cx = status_size.cy = 0;
    }

    wnd_msg = mswin_hwnd_from_winid(WIN_MESSAGE);
    if (IsWindow(wnd_msg)) {
        mswin_message_window_size(wnd_msg, &msg_size);
    } else {
        msg_size.cx = msg_size.cy = 0;
    }

    cmd_size.cx = cmd_size.cy = 0;
    if (GetNHApp()->bCmdPad && IsWindow(GetNHApp()->hCmdWnd)) {
        mswin_command_window_size(GetNHApp()->hCmdWnd, &cmd_size);
    }

/* set window positions */

/* calculate the application windows size */
#if defined(WIN_CE_POCKETPC)
    SetRect(&wnd_rect, visible_rt.left, visible_rt.top, visible_rt.right,
            visible_rt.bottom);
    if (sip.fdwFlags & SIPF_ON)
        cmd_size.cx = cmd_size.cy = 0; /* hide keypad window */
#else
    SetRect(&wnd_rect, client_rt.left, client_rt.top, client_rt.right,
            client_rt.bottom);
#endif

#if !defined(WIN_CE_SMARTPHONE)
    /* other ports have it at the bottom of the screen */
    cmd_size.cx = (wnd_rect.right - wnd_rect.left);
    cmd_org.x = wnd_rect.left;
    cmd_org.y = wnd_rect.bottom - cmd_size.cy;
    wnd_rect.bottom -= cmd_size.cy;
#endif

    /* status window */
    switch (iflags.wc_align_status) {
    case ALIGN_LEFT:
        status_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
        status_size.cy =
            (wnd_rect.bottom - wnd_rect.top); // that won't look good
        status_org.x = wnd_rect.left;
        status_org.y = wnd_rect.top;
        wnd_rect.left += status_size.cx;
        break;

    case ALIGN_RIGHT:
        status_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
        status_size.cy =
            (wnd_rect.bottom - wnd_rect.top); // that won't look good
        status_org.x = wnd_rect.right - status_size.cx;
        status_org.y = wnd_rect.top;
        wnd_rect.right -= status_size.cx;
        break;

    case ALIGN_TOP:
        status_size.cx = (wnd_rect.right - wnd_rect.left);
        status_org.x = wnd_rect.left;
        status_org.y = wnd_rect.top;
        wnd_rect.top += status_size.cy;
        break;

    case ALIGN_BOTTOM:
    default:
        status_size.cx = (wnd_rect.right - wnd_rect.left);
        status_org.x = wnd_rect.left;
        status_org.y = wnd_rect.bottom - status_size.cy;
        wnd_rect.bottom -= status_size.cy;
        break;
    }

    /* message window */
    switch (iflags.wc_align_message) {
    case ALIGN_LEFT:
#if defined(WIN_CE_SMARTPHONE)
        /* smartphone has a keypad window on the right (bottom) side of the
         * message window */
        msg_size.cx = cmd_size.cx = max(msg_size.cx, cmd_size.cx);
        msg_size.cy = (wnd_rect.bottom - wnd_rect.top) - cmd_size.cy;
        msg_org.x = cmd_org.x = wnd_rect.left;
        msg_org.y = wnd_rect.top;
        cmd_org.y = msg_org.y + msg_size.cy;
#else
        msg_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
        msg_size.cy = (wnd_rect.bottom - wnd_rect.top);
        msg_org.x = wnd_rect.left;
        msg_org.y = wnd_rect.top;
#endif
        wnd_rect.left += msg_size.cx;

        break;

    case ALIGN_RIGHT:
#if defined(WIN_CE_SMARTPHONE)
        /* smartphone has a keypad window on the right (bottom) side of the
         * message window */
        msg_size.cx = cmd_size.cx = max(msg_size.cx, cmd_size.cx);
        msg_size.cy = (wnd_rect.bottom - wnd_rect.top) - cmd_size.cy;
        msg_org.x = cmd_org.x = wnd_rect.right - msg_size.cx;
        msg_org.y = wnd_rect.top;
        cmd_org.y = msg_org.y + msg_size.cy;
#else
        msg_size.cx = (wnd_rect.right - wnd_rect.left) / 4;
        msg_size.cy = (wnd_rect.bottom - wnd_rect.top);
        msg_org.x = wnd_rect.right - msg_size.cx;
        msg_org.y = wnd_rect.top;
#endif

        wnd_rect.right -= msg_size.cx;
        break;

    case ALIGN_TOP:
#if defined(WIN_CE_SMARTPHONE)
        /* smartphone has a keypad window on the right side of the message
         * window */
        msg_size.cy = cmd_size.cy = max(msg_size.cy, cmd_size.cy);
        msg_size.cx = (wnd_rect.right - wnd_rect.left) - cmd_size.cx;
        msg_org.x = wnd_rect.left;
        cmd_org.x = msg_org.x + msg_size.cx;
        msg_org.y = cmd_org.y = wnd_rect.bottom - msg_size.cy;
#else
        msg_size.cx = (wnd_rect.right - wnd_rect.left);
        msg_org.x = wnd_rect.left;
        msg_org.y = wnd_rect.top;
#endif
        wnd_rect.top += msg_size.cy;
        break;

    case ALIGN_BOTTOM:
    default:
#if defined(WIN_CE_SMARTPHONE)
        /* smartphone has a keypad window on the right side of the message
         * window */
        msg_size.cy = cmd_size.cy = max(msg_size.cy, cmd_size.cy);
        msg_size.cx = (wnd_rect.right - wnd_rect.left) - cmd_size.cx;
        msg_org.x = wnd_rect.left;
        cmd_org.x = msg_org.x + msg_size.cx;
        msg_org.y = cmd_org.y = wnd_rect.bottom - msg_size.cy;
#else
        msg_size.cx = (wnd_rect.right - wnd_rect.left);
        msg_org.x = wnd_rect.left;
        msg_org.y = wnd_rect.bottom - msg_size.cy;
#endif
        wnd_rect.bottom -= msg_size.cy;
        break;
    }

    map_org.x = wnd_rect.left;
    map_org.y = wnd_rect.top;
    map_size.cx = wnd_rect.right - wnd_rect.left;
    map_size.cy = wnd_rect.bottom - wnd_rect.top;

    /* go through the windows list and adjust sizes */
    for (i = 0; i < MAXWINDOWS; i++) {
        if (GetNHApp()->windowlist[i].win
            && !GetNHApp()->windowlist[i].dead) {
            switch (GetNHApp()->windowlist[i].type) {
            case NHW_MESSAGE:
                MoveWindow(GetNHApp()->windowlist[i].win, msg_org.x,
                           msg_org.y, msg_size.cx, msg_size.cy, TRUE);
                break;
            case NHW_MAP:
                MoveWindow(GetNHApp()->windowlist[i].win, map_org.x,
                           map_org.y, map_size.cx, map_size.cy, TRUE);
                break;
            case NHW_STATUS:
                MoveWindow(GetNHApp()->windowlist[i].win, status_org.x,
                           status_org.y, status_size.cx, status_size.cy,
                           TRUE);
                break;

            case NHW_TEXT:
            case NHW_MENU:
            case NHW_RIP: {
                POINT menu_org;
                SIZE menu_size;

                menu_org.x = client_rt.left;
                menu_org.y = client_rt.top;
#if defined(WIN_CE_POCKETPC)
                menu_size.cx = min(sip.rcVisibleDesktop.right
                                       - sip.rcVisibleDesktop.left,
                                   client_rt.right - client_rt.left);
                menu_size.cy = min(sip.rcVisibleDesktop.bottom
                                       - sip.rcVisibleDesktop.top,
                                   client_rt.bottom - client_rt.top);
#else
                menu_size.cx = client_rt.right - client_rt.left;
                menu_size.cy = client_rt.bottom - client_rt.top;
#endif

#if defined(WIN_CE_SMARTPHONE)
                /* leave room for the command window */
                if (GetNHApp()->windowlist[i].type == NHW_MENU) {
                    menu_size.cy -= cmd_size.cy;
                }

                /* dialogs are popup windows unde SmartPhone so we need
                   to convert to screen coordinates */
                ClientToScreen(GetNHApp()->hMainWnd, &menu_org);
#endif
                MoveWindow(GetNHApp()->windowlist[i].win, menu_org.x,
                           menu_org.y, menu_size.cx, menu_size.cy, TRUE);
            } break;
            }
            ShowWindow(GetNHApp()->windowlist[i].win, SW_SHOW);
            InvalidateRect(GetNHApp()->windowlist[i].win, NULL, TRUE);
        }
    }

    if (IsWindow(GetNHApp()->hCmdWnd)) {
        /* show command window only if it exists and
           the game is ready (plname is set) */
        if (GetNHApp()->bCmdPad && cmd_size.cx > 0 && cmd_size.cy > 0
            && *plname) {
            MoveWindow(GetNHApp()->hCmdWnd, cmd_org.x, cmd_org.y, cmd_size.cx,
                       cmd_size.cy, TRUE);
            ShowWindow(GetNHApp()->hCmdWnd, SW_SHOW);
        } else {
            ShowWindow(GetNHApp()->hCmdWnd, SW_HIDE);
        }
    }
}
Esempio n. 2
0
/* Set map display mode */
void
mswin_select_map_mode(int mode)
{
    HMENU hmenuMap;
    PNHMainWindow data;
    winid map_id;

    map_id = WIN_MAP;
    data = (PNHMainWindow) GetWindowLong(GetNHApp()->hMainWnd, GWL_USERDATA);
#if defined(WIN_CE_SMARTPHONE)
    /* Smartphone manu has only 2 items */
    hmenuMap = _get_main_menu(ID_VIEW);
#else
    hmenuMap = _get_main_menu(ID_MAP);
#endif

    /* override for Rogue level */
    if (Is_rogue_level(&u.uz) && !IS_MAP_ASCII(mode))
        return;

    /* set map mode menu mark */
    if (IS_MAP_ASCII(mode)) {
        CheckMenuRadioItem(hmenuMap, IDM_MAP_TILES, IDM_MAP_FIT_TO_SCREEN,
                           mapmode2menuid(IS_MAP_FIT_TO_SCREEN(mode)
                                              ? data->mapAcsiiModeSave
                                              : mode),
                           MF_BYCOMMAND);
    } else {
        CheckMenuRadioItem(hmenuMap, IDM_MAP_TILES, IDM_MAP_FIT_TO_SCREEN,
                           mapmode2menuid(MAP_MODE_TILES), MF_BYCOMMAND);
    }

#if defined(WIN_CE_SMARTPHONE)
    /* update "Fit To Screen" item text */
    {
        TCHAR wbuf[BUFSZ];
        TBBUTTONINFO tbbi;

        ZeroMemory(wbuf, sizeof(wbuf));
        if (!LoadString(GetNHApp()->hApp,
                        (IS_MAP_FIT_TO_SCREEN(mode) ? IDS_CAP_NORMALMAP
                                                    : IDS_CAP_ENTIREMAP),
                        wbuf, BUFSZ)) {
            panic("cannot load main menu strings");
        }

        ZeroMemory(&tbbi, sizeof(tbbi));
        tbbi.cbSize = sizeof(tbbi);
        tbbi.dwMask = TBIF_TEXT;
        tbbi.pszText = wbuf;
        if (!SendMessage(GetNHApp()->hMenuBar, TB_SETBUTTONINFO,
                         IDM_MAP_FIT_TO_SCREEN, (LPARAM) &tbbi)) {
            error("Cannot update IDM_MAP_FIT_TO_SCREEN menu item.");
        }
    }
#else
    /* set fit-to-screen mode mark */
    CheckMenuItem(hmenuMap, IDM_MAP_FIT_TO_SCREEN,
                  MF_BYCOMMAND | (IS_MAP_FIT_TO_SCREEN(mode) ? MF_CHECKED
                                                             : MF_UNCHECKED));
#endif

    if (IS_MAP_ASCII(iflags.wc_map_mode)
        && !IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
        data->mapAcsiiModeSave = iflags.wc_map_mode;
    }

    iflags.wc_map_mode = mode;

    /*
    ** first, check if WIN_MAP has been inialized.
    ** If not - attempt to retrieve it by type, then check it again
    */
    if (WIN_MAP != WIN_ERR)
        mswin_map_mode(mswin_hwnd_from_winid(WIN_MAP), mode);
}
Esempio n. 3
0
void mswin_display_RIP_window (HWND hWnd)
{
	MSG msg;
	RECT rt;
	PNHRIPWindow data;
	HWND mapWnd;
	RECT riprt;
	RECT clientrect;
	RECT textrect;
	HDC hdc;
	HFONT OldFont;

	data = (PNHRIPWindow)GetWindowLong(hWnd, GWL_USERDATA);

	GetNHApp()->hPopupWnd = hWnd;
	mapWnd = mswin_hwnd_from_winid(WIN_MAP);
	if( !IsWindow(mapWnd) ) mapWnd = GetNHApp()->hMainWnd;
	GetWindowRect(mapWnd, &rt);
	GetWindowRect(hWnd, &riprt);
	GetClientRect (hWnd, &clientrect);
	textrect = clientrect;
	textrect.top += RIP_OFFSET_Y;
	textrect.left += RIP_OFFSET_X;
	textrect.right -= RIP_OFFSET_X;
	if (data->window_text)
	{
	    hdc = GetDC (hWnd);
	    OldFont = SelectObject (hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE));
	    DrawText (hdc, data->window_text, strlen(data->window_text), &textrect,
		DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
	    SelectObject (hdc, OldFont);
	    ReleaseDC(hWnd, hdc);
	}
	if (textrect.right - textrect.left > RIP_WIDTH)
	    clientrect.right = textrect.right + RIP_OFFSET_X - clientrect.right;
	else
	    clientrect.right = textrect.left + 2 * RIP_OFFSET_X + RIP_WIDTH - clientrect.right;
	clientrect.bottom = textrect.bottom + RIP_HEIGHT + RIP_OFFSET_Y - clientrect.bottom;
	GetWindowRect (GetDlgItem(hWnd, IDOK), &textrect);
	textrect.right -= textrect.left;
	textrect.bottom -= textrect.top;
	clientrect.bottom += textrect.bottom + RIP_OFFSET_Y;
	riprt.right -= riprt.left;
	riprt.bottom -= riprt.top;
	riprt.right += clientrect.right;
	riprt.bottom += clientrect.bottom;
	rt.left += (rt.right - rt.left - riprt.right) / 2;
	rt.top += (rt.bottom - rt.top - riprt.bottom) / 2;

	MoveWindow(hWnd, rt.left, rt.top, riprt.right, riprt.bottom, TRUE);
	GetClientRect (hWnd, &clientrect);
	MoveWindow (GetDlgItem(hWnd, IDOK),
	    (clientrect.right - clientrect.left - textrect.right) / 2,
	    clientrect.bottom - textrect.bottom - RIP_OFFSET_Y, textrect.right, textrect.bottom, TRUE);
	ShowWindow(hWnd, SW_SHOW);

	while( IsWindow(hWnd) &&
		   GetMessage(&msg, NULL, 0, 0)!=0 ) {
		if( !IsDialogMessage(hWnd, &msg) ) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	GetNHApp()->hPopupWnd = NULL;
}
Esempio n. 4
0
/*
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
*/
LRESULT CALLBACK
MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PNHMainWindow data;

    switch (message) {
    /*-----------------------------------------------------------------------*/
    case WM_CREATE: {
#if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
        SHMENUBARINFO menubar;
#endif
        /* set window data */
        data = (PNHMainWindow) malloc(sizeof(NHMainWindow));
        if (!data)
            panic("out of memory");
        ZeroMemory(data, sizeof(NHMainWindow));
        data->mapAcsiiModeSave = MAP_MODE_ASCII12x16;
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) data);

        GetNHApp()->hMainWnd = hWnd;

/* create menu bar */
#if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
        ZeroMemory(&menubar, sizeof(menubar));
        menubar.cbSize = sizeof(menubar);
        menubar.hwndParent = hWnd;
        menubar.dwFlags = 0;
        menubar.nToolBarId = IDC_WINHACK;
        menubar.hInstRes = GetNHApp()->hApp;
#if defined(WIN_CE_POCKETPC)
        menubar.nBmpId = IDB_MENUBAR;
        menubar.cBmpImages = 2;
#else
        menubar.nBmpId = 0;
        menubar.cBmpImages = 0;
#endif
        if (!SHCreateMenuBar(&menubar))
            panic("cannot create menu");
        GetNHApp()->hMenuBar = menubar.hwndMB;
#else
        GetNHApp()->hMenuBar = CommandBar_Create(GetNHApp()->hApp, hWnd, 1);
        if (!GetNHApp()->hMenuBar)
            panic("cannot create menu");
        CommandBar_InsertMenubar(GetNHApp()->hMenuBar, GetNHApp()->hApp,
                                 IDC_WINHACK, 0);
#endif
        CheckMenuItem(
            _get_main_menu(ID_VIEW), IDM_VIEW_KEYPAD,
            MF_BYCOMMAND | (GetNHApp()->bCmdPad ? MF_CHECKED : MF_UNCHECKED));

    } break;

    /*-----------------------------------------------------------------------*/

    case WM_MSNH_COMMAND:
        onMSNHCommand(hWnd, wParam, lParam);
        break;

    /*-----------------------------------------------------------------------*/

    case WM_KEYDOWN:
        data = (PNHMainWindow) GetWindowLong(hWnd, GWL_USERDATA);

        /* translate arrow keys into nethack commands */
        switch (wParam) {
        case VK_LEFT:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window one line left */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
                            MAKEWPARAM(SB_LINEUP, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_W));
            }
            return 0;

        case VK_RIGHT:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window one line right */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
                            MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_E));
            }
            return 0;

        case VK_UP:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window one line up */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
                            MAKEWPARAM(SB_LINEUP, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_N));
            }
            return 0;

        case VK_DOWN:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window one line down */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
                            MAKEWPARAM(SB_LINEDOWN, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_S));
            }
            return 0;

        case VK_HOME:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window to upper left corner */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
                            MAKEWPARAM(SB_THUMBTRACK, 0), (LPARAM) NULL);

                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
                            MAKEWPARAM(SB_THUMBTRACK, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_NW));
            }
            return 0;

        case VK_END:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window to lower right corner */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
                            MAKEWPARAM(SB_THUMBTRACK, ROWNO), (LPARAM) NULL);

                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_HSCROLL,
                            MAKEWPARAM(SB_THUMBTRACK, COLNO), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_SW));
            }
            return 0;

        case VK_PRIOR:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window one page up */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
                            MAKEWPARAM(SB_PAGEUP, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_NE));
            }
            return 0;

        case VK_NEXT:
            if (STATEON(VK_CONTROL)) {
                /* scroll map window one page down */
                SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_VSCROLL,
                            MAKEWPARAM(SB_PAGEDOWN, 0), (LPARAM) NULL);
            } else {
                NHEVENT_KBD(KEYTABLE(KEY_SE));
            }
            return 0;

        case VK_DECIMAL:
        case VK_DELETE:
            NHEVENT_KBD(KEYTABLE(KEY_WAITLOOK));
            return 0;

        case VK_INSERT:
            NHEVENT_KBD(KEYTABLE(KEY_INV));
            return 0;

        case VK_SUBTRACT:
            NHEVENT_KBD(KEYTABLE(KEY_MINUS));
            return 0;

        case VK_ADD:
            NHEVENT_KBD(KEYTABLE(KEY_PLUS));
            return 0;

        case VK_CLEAR: /* This is the '5' key */
            NHEVENT_KBD(KEYTABLE(KEY_GOINTERESTING));
            return 0;

        case VK_F4:
            if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
                mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode)
                                          ? data->mapAcsiiModeSave
                                          : MAP_MODE_TILES);
            } else {
                mswin_select_map_mode(IS_MAP_ASCII(iflags.wc_map_mode)
                                          ? MAP_MODE_ASCII_FIT_TO_SCREEN
                                          : MAP_MODE_TILES_FIT_TO_SCREEN);
            }
            return 0;

        case VK_F5:
            if (IS_MAP_ASCII(iflags.wc_map_mode)) {
                if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
                    mswin_select_map_mode(MAP_MODE_TILES_FIT_TO_SCREEN);
                } else {
                    mswin_select_map_mode(MAP_MODE_TILES);
                }
            } else {
                if (IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode)) {
                    mswin_select_map_mode(MAP_MODE_ASCII_FIT_TO_SCREEN);
                } else {
                    mswin_select_map_mode(data->mapAcsiiModeSave);
                }
            }
            return 0;

        case VK_RETURN: {
            int x, y;
            if (WIN_MAP != WIN_ERR) {
                mswin_map_get_cursor(mswin_hwnd_from_winid(WIN_MAP), &x, &y);
            } else {
                x = u.ux;
                y = u.uy;
            }
            NHEVENT_MS(CLICK_1, x, y);
        }
            return 0;
        }

#if defined(WIN_CE_SMARTPHONE)
        if (GetNHApp()->bCmdPad
            && NHSPhoneTranslateKbdMessage(wParam, lParam, TRUE))
            return 0;
#endif
        return 1; /* end of WM_KEYDOWN */

/*-----------------------------------------------------------------------*/

#if defined(WIN_CE_SMARTPHONE)
    case WM_KEYUP:
        if (GetNHApp()->bCmdPad
            && NHSPhoneTranslateKbdMessage(wParam, lParam, FALSE))
            return 0;
        return 1; /* end of WM_KEYUP */
#endif
    /*-----------------------------------------------------------------------*/

    case WM_CHAR:
#if defined(WIN_CE_SMARTPHONE)
        /* if smartphone cmdpad is up then translation happens - disable
           WM_CHAR processing
           to avoid double input */
        if (GetNHApp()->bCmdPad) {
            return 1;
        }
#endif

        if (wParam == '\n' || wParam == '\r' || wParam == C('M'))
            return 0; /* we already processed VK_RETURN */

        /* all characters go to nethack except Ctrl-P that scrolls message
         * window up */
        if (wParam == C('P') || wParam == C('p')) {
            SendMessage(mswin_hwnd_from_winid(WIN_MESSAGE), WM_VSCROLL,
                        MAKEWPARAM(SB_LINEUP, 0), (LPARAM) NULL);
        } else {
            NHEVENT_KBD((lParam & 1 << 29) ? M(tolower(wParam)) : wParam);
        }
        return 0;

    /*-----------------------------------------------------------------------*/

    case WM_COMMAND:
        /* process commands - menu commands mostly */
        if (IsWindow(GetNHApp()->hPopupWnd)) {
            return SendMessage(GetNHApp()->hPopupWnd, message, wParam,
                               lParam);
        } else if (onWMCommand(hWnd, wParam, lParam))
            return DefWindowProc(hWnd, message, wParam, lParam);
        else
            return 0;

    /*-----------------------------------------------------------------------*/

    case WM_ACTIVATE:
        if (LOWORD(wParam) != WA_INACTIVE) {
#if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
            if (GetNHApp()->bFullScreen)
                SHFullScreen(GetNHApp()->hMainWnd,
                             SHFS_HIDETASKBAR | SHFS_HIDESTARTICON);
            else
                SHFullScreen(GetNHApp()->hMainWnd,
                             SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON);
#endif
            mswin_layout_main_window(NULL);
        }
        break;

    case WM_SETTINGCHANGE:
#if defined(WIN_CE_POCKETPC) || defined(WIN_CE_SMARTPHONE)
        if (GetNHApp()->bFullScreen)
            SHFullScreen(GetNHApp()->hMainWnd,
                         SHFS_HIDETASKBAR | SHFS_HIDESTARTICON);
        else
            SHFullScreen(GetNHApp()->hMainWnd,
                         SHFS_SHOWTASKBAR | SHFS_SHOWSTARTICON);
#endif
        mswin_layout_main_window(NULL);
        break;

    case WM_SIZE:
        mswin_layout_main_window(NULL);
        break;

    /*-----------------------------------------------------------------------*/

    case WM_SETFOCUS:
        /* if there is a menu window out there -
           transfer input focus to it */
        if (IsWindow(GetNHApp()->hPopupWnd)) {
            SetFocus(GetNHApp()->hPopupWnd);
        }
        break;

    /*-----------------------------------------------------------------------*/

    case WM_CLOSE: {
/* exit gracefully */
#ifdef SAFERHANGUP
        /* destroy popup window - it has its own loop and we need to
           return control to NetHack core at this point */
        if (IsWindow(GetNHApp()->hPopupWnd))
            SendMessage(GetNHApp()->hPopupWnd, WM_COMMAND, IDCANCEL, 0);

        /* tell NetHack core that "hangup" is requested */
        hangup(1);
#else
        dosave0();
        terminate(EXIT_SUCCESS);
#endif
    }
        return 0;

    /*-----------------------------------------------------------------------*/

    case WM_DESTROY: {
        /* apparently we never get here
           TODO: work on exit routines - need to send
           WM_QUIT somehow */

        /* clean up */
        free((PNHMainWindow) GetWindowLong(hWnd, GWL_USERDATA));
        SetWindowLong(hWnd, GWL_USERDATA, (LONG) 0);

        terminate(EXIT_SUCCESS);
    } break;

    /*-----------------------------------------------------------------------*/

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
Esempio n. 5
0
void mswin_finish_rip_text(winid wid)
{
	SendMessage (mswin_hwnd_from_winid(wid), WM_MSNH_COMMAND,  MSNH_MSG_DIED, 0);
}
Esempio n. 6
0
void mswin_display_splash_window (BOOL show_ver)
{
	MSG msg;
	HWND mapWnd;
	int left, top;
	RECT splashrt;
	RECT clientrt;
	RECT controlrt;
	HWND hWnd;
	int buttop;
	int strsize = 0;
	int bufsize = BUFSZ;

	char *buf = malloc(bufsize);
	if (buf == NULL)
	    panic("out of memory");
	buf[0] = '\0';

	hWnd = CreateDialog(GetNHApp()->hApp, MAKEINTRESOURCE(IDD_SPLASH),
	    GetNHApp()->hMainWnd, NHSplashWndProc);
	if( !hWnd ) panic("Cannot create Splash window");
	mswin_init_splashfonts(hWnd);
	GetNHApp()->hPopupWnd = hWnd;
	mapWnd = mswin_hwnd_from_winid(WIN_MAP);
	if( !IsWindow(mapWnd) ) mapWnd = GetNHApp()->hMainWnd;
	/* Get control size */
	GetWindowRect (GetDlgItem(hWnd, IDOK), &controlrt);
	controlrt.right -= controlrt.left;
	controlrt.bottom -= controlrt.top;
	/* Get current client area */
	GetClientRect (hWnd, &clientrt);
	/* Get window size */
	GetWindowRect(hWnd, &splashrt);
	splashrt.right -= splashrt.left;
	splashrt.bottom -= splashrt.top;
	/* Get difference between requested client area and current value */
	splashrt.right += SPLASH_WIDTH + SPLASH_OFFSET_X * 2 - clientrt.right;
	splashrt.bottom += SPLASH_HEIGHT + controlrt.bottom + SPLASH_OFFSET_Y * 3 - clientrt.bottom;
	/* Place the window centered */
	/* On the screen, not on the parent window */
	left = (GetSystemMetrics(SM_CXSCREEN) - splashrt.right) / 2;
	top = (GetSystemMetrics(SM_CYSCREEN) - splashrt.bottom) / 2;
	MoveWindow(hWnd, left, top, splashrt.right, splashrt.bottom, TRUE);
	/* Place the OK control */
	GetClientRect (hWnd, &clientrt);
	MoveWindow (GetDlgItem(hWnd, IDOK),
	    (clientrt.right - clientrt.left - controlrt.right) / 2,
	    clientrt.bottom - controlrt.bottom - SPLASH_OFFSET_Y,
	    controlrt.right, controlrt.bottom, TRUE);
	buttop = clientrt.bottom - controlrt.bottom - SPLASH_OFFSET_Y;
	/* Place the text control */
	GetWindowRect (GetDlgItem(hWnd, IDC_EXTRAINFO), &controlrt);
	controlrt.right -= controlrt.left;
	controlrt.bottom -= controlrt.top;
	GetClientRect (hWnd, &clientrt);
	MoveWindow (GetDlgItem(hWnd, IDC_EXTRAINFO),
	    clientrt.left + SPLASH_OFFSET_X,
	    buttop - controlrt.bottom - SPLASH_OFFSET_Y,
	    clientrt.right - 2 * SPLASH_OFFSET_X, controlrt.bottom, TRUE);
	/* Fill the text control */
	Sprintf(buf, "%s\r\n%s\r\n%s\r\n\r\n", COPYRIGHT_BANNER_A, COPYRIGHT_BANNER_B,
	    COPYRIGHT_BANNER_C);
	strsize = strlen(buf);
	
	if (show_ver) {
	    /* Show complete version information */
	    dlb *f;

	    getversionstring(buf + strsize);
	    strcat(buf, "\r\n\r\n");
	    strsize = strlen(buf);

	    /* Add compile options */
	    f = dlb_fopen(OPTIONS_USED, RDTMODE);
	    if (f) {
		char line[LLEN + 1];
		
		while (dlb_fgets(line, LLEN, f)) {
		    size_t len;
		    len = strlen(line);
		    if (len > 0 && line[len - 1] == '\n') {
			line[len - 1] = '\r';
			line[len] = '\n';
			line[len + 1] = '\0';
			len++;
		    }
		    if (strsize + (int)len + 1 > bufsize)
		    {
			bufsize += BUFSZ;
			buf = realloc(buf, bufsize);
			if (buf == NULL)
			    panic("out of memory");
		    }
		    strcat(buf, line);
		    strsize += len;
		}
		(void) dlb_fclose(f);
	    }
	} else {
	    /* Show news, if any */
	    if (iflags.news) {	    
		FILE *nf;
		
		iflags.news = 0; /* prevent newgame() from re-displaying news */
		nf = fopen(NEWS, "r");
		if (nf != NULL) {
		    char line[LLEN + 1];
		    
		    while (fgets(line, LLEN, nf)) {
			size_t len;
			len = strlen(line);
			if (len > 0 && line[len - 1] == '\n') {
			    line[len - 1] = '\r';
			    line[len] = '\n';
			    line[len + 1] = '\0';
			    len++;
			}
			if (strsize + (int)len + 1 > bufsize)
			{
			    bufsize += BUFSZ;
			    buf = realloc(buf, bufsize);
			    if (buf == NULL)
				panic("out of memory");
			}
			strcat(buf, line);
			strsize += len;
		    }
		    (void) fclose(nf);
		} 
		else
		{
		    strcat(buf, "No news.");
		}
	    }
	}
	SetWindowText(GetDlgItem(hWnd, IDC_EXTRAINFO), buf);
	free(buf);
	ShowWindow(hWnd, SW_SHOW);
	
	while( IsWindow(hWnd) &&
	    GetMessage(&msg, NULL, 0, 0)!=0 ) {
	    if( !IsDialogMessage(hWnd, &msg) ) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	    }
	}
	
	GetNHApp()->hPopupWnd = NULL;
	mswin_destroy_splashfonts();
}
Esempio n. 7
0
void
mswin_display_RIP_window(HWND hWnd)
{
    MSG msg;
    RECT rt;
    PNHRIPWindow data;
    HWND mapWnd;
    RECT riprt;
    RECT clientrect;
    RECT textrect;
    HFONT OldFont;
    MonitorInfo monitorInfo;

    win10_monitor_info(hWnd, &monitorInfo);

    data = (PNHRIPWindow) GetWindowLongPtr(hWnd, GWLP_USERDATA);

    data->x = (int)(RIP_OFFSET_X * monitorInfo.scale);
    data->y = (int)(RIP_OFFSET_Y * monitorInfo.scale);
    data->width = (int)(RIP_WIDTH * monitorInfo.scale);
    data->height = (int)(RIP_HEIGHT * monitorInfo.scale);
    data->graveX = (int)(RIP_GRAVE_X * monitorInfo.scale);
    data->graveY = (int)(RIP_GRAVE_Y * monitorInfo.scale);
    data->graveWidth = (int)(RIP_GRAVE_WIDTH * monitorInfo.scale);
    data->graveHeight = (int)(RIP_GRAVE_HEIGHT * monitorInfo.scale);

    GetNHApp()->hPopupWnd = hWnd;
    mapWnd = mswin_hwnd_from_winid(WIN_MAP);
    if (!IsWindow(mapWnd))
        mapWnd = GetNHApp()->hMainWnd;
    GetWindowRect(mapWnd, &rt);
    GetWindowRect(hWnd, &riprt);
    GetClientRect(hWnd, &clientrect);
    textrect = clientrect;
    textrect.top += data->y;
    textrect.left += data->x;
    textrect.right -= data->x;
    if (data->window_text) {
        HDC hdc = GetDC(hWnd);
        OldFont = SelectObject(hdc, mswin_get_font(NHW_TEXT, 0, hdc, FALSE)->hFont);
        DrawText(hdc, data->window_text, strlen(data->window_text), &textrect,
                 DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
        SelectObject(hdc, OldFont);
        ReleaseDC(hWnd, hdc);
    }
    if (textrect.right - textrect.left > data->width)
        clientrect.right = textrect.right + data->y - clientrect.right;
    else
        clientrect.right =
            textrect.left + 2 * data->x + data->width - clientrect.right;
    clientrect.bottom =
        textrect.bottom + data->height + data->y - clientrect.bottom;
    GetWindowRect(GetDlgItem(hWnd, IDOK), &textrect);
    textrect.right -= textrect.left;
    textrect.bottom -= textrect.top;
    clientrect.bottom += textrect.bottom + data->y;
    riprt.right -= riprt.left;
    riprt.bottom -= riprt.top;
    riprt.right += clientrect.right;
    riprt.bottom += clientrect.bottom;
    rt.left += (rt.right - rt.left - riprt.right) / 2;
    rt.top += (rt.bottom - rt.top - riprt.bottom) / 2;

    MoveWindow(hWnd, rt.left, rt.top, riprt.right, riprt.bottom, TRUE);
    GetClientRect(hWnd, &clientrect);
    MoveWindow(GetDlgItem(hWnd, IDOK),
               (clientrect.right - clientrect.left - textrect.right) / 2,
               clientrect.bottom - textrect.bottom - data->y,
               textrect.right, textrect.bottom, TRUE);
    ShowWindow(hWnd, SW_SHOW);

    while (IsWindow(hWnd) && GetMessage(&msg, NULL, 0, 0) != 0) {
        if (!IsDialogMessage(hWnd, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    GetNHApp()->hPopupWnd = NULL;
}
Esempio n. 8
0
/*
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
*/
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PNHMainWindow data;

	switch (message) 
	{
		case WM_CREATE:
			/* set window data */
			data = (PNHMainWindow)malloc(sizeof(NHMainWindow));
			if( !data ) panic("out of memory");
			ZeroMemory(data, sizeof(NHMainWindow));
			data->mapAcsiiModeSave = MAP_MODE_ASCII12x16;
			SetWindowLong(hWnd, GWL_USERDATA, (LONG)data);

			GetNHApp()->hMainWnd = hWnd;
		break;

		case WM_MSNH_COMMAND:
			onMSNHCommand(hWnd, wParam, lParam);
		break;

        case WM_KEYDOWN: 
		{
			data = (PNHMainWindow)GetWindowLong(hWnd, GWL_USERDATA);

			/* translate arrow keys into nethack commands */
            switch (wParam) 
            { 
			case VK_LEFT:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window one line left */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_HSCROLL,
						MAKEWPARAM(SB_LINEUP, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_W));
				}
			return 0;

			case VK_RIGHT:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window one line right */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_HSCROLL,
						MAKEWPARAM(SB_LINEDOWN, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_E));
				}
			return 0;

			case VK_UP:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window one line up */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_VSCROLL,
						MAKEWPARAM(SB_LINEUP, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_N));
				}
			return 0;

			case VK_DOWN:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window one line down */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_VSCROLL,
						MAKEWPARAM(SB_LINEDOWN, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_S));
				}
			return 0;

			case VK_HOME:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window to upper left corner */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_VSCROLL,
						MAKEWPARAM(SB_THUMBTRACK, 0),
						(LPARAM)NULL
					);

					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_HSCROLL,
						MAKEWPARAM(SB_THUMBTRACK, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_NW));
				}
			return 0;

			case VK_END:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window to lower right corner */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_VSCROLL,
						MAKEWPARAM(SB_THUMBTRACK, ROWNO),
						(LPARAM)NULL
					);

					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_HSCROLL,
						MAKEWPARAM(SB_THUMBTRACK, COLNO),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_SW));
				}
			return 0;

			case VK_PRIOR:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window one page up */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_VSCROLL,
						MAKEWPARAM(SB_PAGEUP, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_NE));
				}
			return 0;

			case VK_NEXT:
				if( STATEON(VK_CONTROL) ) {
					/* scroll map window one page down */
					SendMessage(
						mswin_hwnd_from_winid(WIN_MAP),
						WM_VSCROLL,
						MAKEWPARAM(SB_PAGEDOWN, 0),
						(LPARAM)NULL
					);
				} else {
					NHEVENT_KBD(KEYTABLE(KEY_SE));
				}
			return 0;

			case VK_DECIMAL:
			case VK_DELETE:
				NHEVENT_KBD(KEYTABLE(KEY_WAITLOOK));
			return 0;

			case VK_INSERT:
				NHEVENT_KBD(KEYTABLE(KEY_INV));
			return 0;

			case VK_SUBTRACT:
				NHEVENT_KBD(KEYTABLE(KEY_MINUS));
			return 0;

			case VK_ADD:
				NHEVENT_KBD(KEYTABLE(KEY_PLUS));
			return 0;

			case VK_CLEAR: /* This is the '5' key */
				NHEVENT_KBD(KEYTABLE(KEY_GOINTERESTING));
			return 0;

			case VK_F4:
				if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
					mswin_select_map_mode(
						IS_MAP_ASCII(iflags.wc_map_mode)? 
							data->mapAcsiiModeSave :
							MAP_MODE_TILES
					);
				} else {
					mswin_select_map_mode(
						IS_MAP_ASCII(iflags.wc_map_mode)?
							MAP_MODE_ASCII_FIT_TO_SCREEN :
							MAP_MODE_TILES_FIT_TO_SCREEN
					);
				}
			return 0;

			case VK_F5:
				if( IS_MAP_ASCII(iflags.wc_map_mode) ) {
					if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
						mswin_select_map_mode(MAP_MODE_TILES_FIT_TO_SCREEN);
					} else {
						mswin_select_map_mode(MAP_MODE_TILES);
					}
				} else {
					if( IS_MAP_FIT_TO_SCREEN(iflags.wc_map_mode) ) {
						mswin_select_map_mode(MAP_MODE_ASCII_FIT_TO_SCREEN);
					} else {
						mswin_select_map_mode(data->mapAcsiiModeSave);
					}
				}
			return 0;

			default: {
				WORD c;
				BYTE kbd_state[256];

				c = 0;
				ZeroMemory(kbd_state, sizeof(kbd_state));
				GetKeyboardState(kbd_state);

				if( ToAscii( wParam, (lParam>>16)&0xFF, kbd_state, &c, 0) ) {
					NHEVENT_KBD( c&0xFF );
					return 0;
				} else {
					return 1;
				}
			}

			} /* end switch */
		} break;

        case WM_SYSCHAR: /* Alt-char pressed */
        {
            /*
              If not nethackmode, don't handle Alt-keys here.
              If no Alt-key pressed it can never be an extended command 
            */
	    if (GetNHApp()->regNetHackMode && ((lParam & 1<<29) != 0))
            {
                unsigned char c = (unsigned char)(wParam & 0xFF);
		unsigned char scancode = (lParam >> 16) & 0xFF;
                if (index(extendedlist, tolower(c)) != 0)
		{
		    NHEVENT_KBD(M(tolower(c)));
		} else if (scancode == (SCANLO + SIZE(scanmap)) - 1) {
		    NHEVENT_KBD(M('?'));
		}
		return 0;
            }
            return DefWindowProc(hWnd, message, wParam, lParam);
        } 
Esempio n. 9
0
LRESULT CALLBACK
GetlinDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    struct getlin_data *data;
    RECT main_rt, text_rt, dlg_rt, edit_rt;
    SIZE dlg_sz;
    TCHAR wbuf[BUFSZ];
    HDC hdc;
    HWND control;
    HWND hwndMap;

#if defined(WIN_CE_POCKETPC)
    SHInputDialog(hWnd, message, wParam);
#endif

    switch (message) {
    case WM_INITDIALOG:
        data = (struct getlin_data *) lParam;
        SetWindowText(hWnd, NH_A2W(data->question, wbuf, sizeof(wbuf)));
        SetWindowLong(hWnd, GWL_USERDATA, lParam);

        /* get title text width */
        SetRect(&text_rt, 0, 0, 100, 50);
        hdc = GetWindowDC(hWnd);
        DrawText(hdc, wbuf, _tcslen(wbuf), &text_rt,
                 DT_CALCRECT | DT_SINGLELINE | DT_NOPREFIX | DT_LEFT
                     | DT_VCENTER);
        ReleaseDC(hWnd, hdc);

        /* center dialog in the main window */
        GetWindowRect(hWnd, &dlg_rt);
        hwndMap = mswin_hwnd_from_winid(WIN_MAP);
        GetWindowRect(IsWindow(hwndMap) ? hwndMap : GetNHApp()->hMainWnd,
                      &main_rt);
        dlg_sz.cx = max(
            dlg_rt.right - dlg_rt.left,
            min(text_rt.right - text_rt.left + GetSystemMetrics(SM_CXICON),
                main_rt.right - main_rt.left));
        dlg_sz.cy =
            min(dlg_rt.bottom - dlg_rt.top, main_rt.bottom - main_rt.top);
        dlg_rt.left = (main_rt.left + main_rt.right - dlg_sz.cx) / 2;
        dlg_rt.right = dlg_rt.left + dlg_sz.cx;
        dlg_rt.top = (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2;
        dlg_rt.bottom = dlg_rt.top + dlg_sz.cy;
        MoveWindow(hWnd, (main_rt.left + main_rt.right - dlg_sz.cx) / 2,
                   (main_rt.top + main_rt.bottom - dlg_sz.cy) / 2, dlg_sz.cx,
                   dlg_sz.cy, TRUE);

        /* change layout of controls */
        GetClientRect(hWnd, &dlg_rt);

        control = GetDlgItem(hWnd, IDC_GETLIN_EDIT);
        GetWindowRect(control, &edit_rt);
        MoveWindow(control, 0, 0, dlg_rt.right - dlg_rt.left,
                   edit_rt.bottom - edit_rt.top, TRUE);

        control = GetDlgItem(hWnd, IDOK);
        GetWindowRect(control, &text_rt);
        MoveWindow(control, 0, edit_rt.bottom - edit_rt.top,
                   (dlg_rt.right - dlg_rt.left) / 2,
                   text_rt.bottom - text_rt.top, TRUE);

        control = GetDlgItem(hWnd, IDCANCEL);
        GetWindowRect(control, &text_rt);
        MoveWindow(control, (dlg_rt.right - dlg_rt.left) / 2,
                   edit_rt.bottom - edit_rt.top,
                   (dlg_rt.right - dlg_rt.left) / 2,
                   text_rt.bottom - text_rt.top, TRUE);

#if defined(WIN_CE_SMARTPHONE)
        NHSPhoneDialogSetup(hWnd, IDC_SPHONE_DIALOGBAR, TRUE, FALSE);
#endif

        /* set focus to the edit control */
        SetFocus(GetDlgItem(hWnd, IDC_GETLIN_EDIT));

        /* tell windows that we've set the focus */
        return FALSE;
        break;

    case WM_COMMAND: {
        TCHAR wbuf[BUFSZ];

        switch (LOWORD(wParam)) {
        /* OK button was pressed */
        case IDOK:
            data = (struct getlin_data *) GetWindowLong(hWnd, GWL_USERDATA);
            SendDlgItemMessage(hWnd, IDC_GETLIN_EDIT, WM_GETTEXT,
                               (WPARAM) sizeof(wbuf), (LPARAM) wbuf);
            NH_W2A(wbuf, data->result, data->result_size);

        /* Fall through. */

        /* cancel button was pressed */
        case IDCANCEL:
            EndDialog(hWnd, wParam);
            return TRUE;
        }
    } break;

#if defined(WIN_CE_SMARTPHONE)
    case WM_HOTKEY:
        if (VK_TBACK == HIWORD(lParam)) {
            SHSendBackToFocusWindow(message, wParam, lParam);
        }
        break;
#endif

    } /* end switch (message) */
    return FALSE;
}