コード例 #1
0
ファイル: wstrings.c プロジェクト: conioh/os-design
BOOL WINAPI IsCharUpperW(
    WCHAR wChar)
{
    WORD ctype1info;

    if (GetStringTypeW(CT_CTYPE1, &wChar, 1, &ctype1info)) {
        if (ctype1info & C1_UPPER) {
            return TRUE;
        } else {
            return FALSE;
        }
    }

    /*
     * GetStringTypeW failed!  The caller is not expecting
     * failure, IsCharLowerW does not have a failure indicator, so we
     * determine the case as best we can.
     */
    RIPMSG1(RIP_WARNING, "IsCharUpper(L'\\x%.4lx') failed", wChar);

    if (IS_UNICODE_BLK1(wChar)) {
        return IsCharUpperA((CHAR)wChar);
    } else {
        return FALSE;
    }
}
コード例 #2
0
ファイル: wstrings.c プロジェクト: conioh/os-design
DWORD WINAPI CharLowerBuffW(
    LPWSTR pwsz,
    DWORD cwch)
{
    int cwchT;
    DWORD i;

    if (cwch == 0) {
        return 0;
    }

    cwchT = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
                pwsz, cwch, pwsz, cwch);

    if (cwchT != 0) {
        return cwchT;
    }

    /*
     * LCMapString failed!  The caller is not expecting failure,
     * CharLowerBuffW does not have a failure indicator, so we
     * convert the buffer to lower case as best we can.
     */
    RIPMSG1(RIP_WARNING, "CharLowerBuffW(%ls) failed", pwsz);

    for (i=0; i < cwch; i++) {
        if (IS_UNICODE_BLK1(pwsz[i]) && IsCharUpperA((char)pwsz[i])) {
            pwsz[i] += 'a'-'A';
        }
    }

    return cwch;
}
コード例 #3
0
ファイル: miscutil.c プロジェクト: conioh/os-design
VOID SetDialogPointer(PWND pwnd, LONG_PTR lPtr) {

    if ((pwnd->cbwndExtra < DLGWINDOWEXTRA)
            || TestWF(pwnd, WFSERVERSIDEPROC)
            || (PpiCurrent() != GETPTI(pwnd)->ppi)) {
        RIPMSG1(RIP_WARNING, "SetDialogPointer: Unexpected pwnd:%#p", pwnd);
        return;
    }

    ((PDIALOG)pwnd)->pdlg = (PDLG)lPtr;

    if (lPtr == 0) {
        pwnd->fnid |= FNID_CLEANEDUP_BIT;
        ClrWF(pwnd, WFDIALOGWINDOW);
    } else {
        if (pwnd->fnid == 0) {
            pwnd->fnid = FNID_DIALOG;
        }
        SetWF(pwnd, WFDIALOGWINDOW);
    }


}
コード例 #4
0
ファイル: wstrings.c プロジェクト: conioh/os-design
LPWSTR WINAPI CharLowerW(
    LPWSTR pwsz)
{
    /*
     * Early out for NULL string or '\0'
     */
    if (pwsz == NULL) {
        return pwsz;
    }

    if (!IS_PTR(pwsz)) {
        if (!LCMapStringW(
                 LOCALE_USER_DEFAULT,
                 LCMAP_LOWERCASE,
                 (LPWSTR)&pwsz,
                 1,
                 (LPWSTR)&pwsz,
                 1
                 )) {
            /*
             * We don't expect LCMapString to fail!  The caller is not expecting
             * failure, CharLowerW does not have a failure indicator, so we do
             * nothing.
             */
            RIPMSG1(RIP_WARNING, "CharLowerW(%#p): LCMapString failed\n", pwsz);
        }

        return pwsz;
    }

    /*
     * pwsz is a null-terminated string
     */
    CharLowerBuffW(pwsz, wcslen(pwsz)+1);
    return pwsz;
}
コード例 #5
0
ファイル: connect.c プロジェクト: Gaikokujin/WinNT4
/***************************************************************************\
* ConnectConv
*
* Description:
* Work function for all Connect cases.
*
* Method:
*
* To reduce the number of windows we use and to simplify how client
* windows handle multiple WM_DDE_ACK messages during initiation, a
* single client window can handle many conversations, each with
* a different server window.
*
* The client window is created and set to a initiation state via the
* GWL_CONVSTATE window word. Initiates are then sent to enumerated server
* window candidates.
* The GWL_CONVSTATE value is used by the DDEML mother windows
* to determine if only one or several ACKs are desired to minimize
* unnessary message traffic.
*
* The client window GWL_CONVCONTEXT? window words are also used by
* Event Windows to pass context information.
*
* Note that all client and server windows are children of the mother
* window. This reduces the number of top level windows that
* WM_DDE_INITIATES need to hit.
*
* Each WM_DDE_ACK that is received by a client window while in the
* initiation state causes it to create a CL_CONV_INFO structure,
* partially initialize it, and link it into its list of CL_CONV_INFO
* structures. The head of the list is pointed to by the GWL_PCI
* client window word.
*
* After each WM_DDE_INITIALIZE is sent, the GWL_PCI value is checked
* to see if it exists and needs initialization to be completed. If
* this is the case the init code knows that at least one ACK was
* received in response to the WM_DDE_INITIALIZE send. The
* initialization of each CL_CONV_INFO struct that needs it is then completed.
*
* Once the broadcasting of WM_DDE_INITIALIZE is done, the init code
* then sets the GWL_CONVSTATE value in the client window to indicate that
* initialization is complete.
*
* Returns:
* The head pci to the client window or NULL if no connections made it.
*
* History:
* 11-1-91 sanfords Created.
\***************************************************************************/
PCL_CONV_INFO ConnectConv(
    PCL_INSTANCE_INFO pcii,
    LATOM laService,
    LATOM laTopic,
    HWND hwndTarget, // 0 implies broadcast
    HWND hwndSkip, // 0 implies no skips - avoids self-connections.
    PCONVCONTEXT pCC,
    HCONVLIST hConvList,
    DWORD clst)
{
    INIT_ENUM ie;
    PCL_CONV_INFO pci;
    PCONV_INFO pcoi;
    GATOM gaService, gaTopic;

    CheckDDECritIn;

    if (hwndTarget && hwndTarget == hwndSkip) {
        return(NULL);
    }

    LeaveDDECrit;
    CheckDDECritOut;

    if (pcii->flags & IIF_UNICODE) {
        ie.hwndClient = CreateWindowW((LPWSTR)(gpsi->atomSysClass[ICLS_DDEMLCLIENTW]),
                                     L"",
                                     WS_CHILD,
                                     0, 0, 0, 0,
                                     pcii->hwndMother,
                                     (HMENU)0,
                                     (HANDLE)0,
                                     (LPVOID)NULL);
    } else {
        ie.hwndClient = CreateWindowA((LPSTR)(gpsi->atomSysClass[ICLS_DDEMLCLIENTA]),
                                     "",
                                     WS_CHILD,
                                     0, 0, 0, 0,
                                     pcii->hwndMother,
                                     (HMENU)0,
                                     (HANDLE)0,
                                     (LPVOID)NULL);
    }

    EnterDDECrit;

    if (ie.hwndClient == 0) {
        return (NULL);
    }

    if (pCC != NULL) {
        if (!NtUserDdeSetQualityOfService(ie.hwndClient, &(pCC->qos), NULL)) {
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            goto Error;
        }
    }
    /*
     * Note that a pci will be created and allocated for each ACK recieved.
     */
    SetConvContext(ie.hwndClient, (LONG *)pCC);
    SetWindowLong(ie.hwndClient, GWL_CONVSTATE, clst);
    SetWindowLong(ie.hwndClient, GWL_SHINST, (LONG)pcii->hInstServer);
    SetWindowLong(ie.hwndClient, GWL_CHINST, (LONG)pcii->hInstClient);

    gaService = LocalToGlobalAtom(laService);
    gaTopic = LocalToGlobalAtom(laTopic);
    ie.lParam = MAKELONG(gaService, gaTopic);
    if (!hwndTarget) {
        ie.hwndSkip = hwndSkip;
        ie.laServiceRequested = laService;
        ie.laTopic = laTopic;
        ie.hConvList = hConvList;
        ie.clst = clst;
    }

    LeaveDDECrit;

    if (hwndTarget) {
        SendMessage(hwndTarget, WM_DDE_INITIATE, (DWORD)ie.hwndClient,
                ie.lParam);
    } else {
        /*
         * Send this message to the nddeagnt app first so it can start
         * the netdde services BEFORE we do an enumeration of windows.
         * This lets things work the first time.  NetDDEAgent caches
         * service status so this is the fastest way to do this.
         */
        HWND hwndAgent = FindWindowW(SZ_NDDEAGNT_CLASS, SZ_NDDEAGNT_TITLE);
        if (hwndAgent) {
            SendMessage(hwndAgent,
                WM_DDE_INITIATE, (WPARAM)ie.hwndClient, ie.lParam);
        }
        EnumWindows((WNDENUMPROC)InitiateEnumerationProc, (LONG)&ie);
    }

    EnterDDECrit;
    /*
     * hConvList may have been destroyed during the enumeration but we are
     * done with it now so no need to revalidate.
     */

#ifdef DEBUG
    {
        WCHAR sz[10];

        if (gaService && GlobalGetAtomName(gaService, sz, 10) == 0) {
            RIPMSG1(RIP_ERROR, "Bad Service Atom after Initiate phase: %lX", (DWORD)gaService);
        }
        if (gaTopic && GlobalGetAtomName(gaTopic, sz, 10) == 0) {
            RIPMSG1(RIP_ERROR, "Bad Topic Atom after Initiate phase: %lX", (DWORD)gaTopic);
        }
    }
#endif // DEBUG

    GlobalDeleteAtom(gaService);
    GlobalDeleteAtom(gaTopic);

    //
    // Get the first pci allocated when a WM_DDE_ACK was recieved.
    //
    pci = (PCL_CONV_INFO)GetWindowLong(ie.hwndClient, GWL_PCI);
    if (pci == NULL) {
Error:
        LeaveDDECrit;
        NtUserDestroyWindow(ie.hwndClient);
        EnterDDECrit;
        return (NULL);
    }

    SetWindowLong(ie.hwndClient, GWL_CONVSTATE, CLST_CONNECTED);
    if (hwndTarget) {
        /*
         * If hwndTarget was NULL, the enumeration proc took care of this.
         */
        pci->hwndReconnect = hwndTarget;
        UserAssert(pci->ci.next == NULL);
        pci->ci.laServiceRequested = laService;
        IncLocalAtomCount(laService); // pci copy
    }

    if (pcii->MonitorFlags & MF_CONV) {
        for (pcoi = (PCONV_INFO)pci; pcoi; pcoi = pcoi->next) {
            MONCONV(pcoi, TRUE);
        }
    }
    return (pci);
}
コード例 #6
0
ファイル: random.c プロジェクト: conioh/os-design
WINUSERAPI HANDLE WINAPI SetSysColorsTemp(
    CONST COLORREF *lpRGBs,
    CONST HBRUSH   *lpBrushes,
    UINT_PTR       cBrushes)      // Count of brushes or handle
{
    UINT cbRGBSize;
    UINT i;
    UINT abElements[COLOR_MAX];

    /*
     * See if we are resetting the colors back to a saved state
     */
    if (lpRGBs == NULL) {

        /*
         * When restoring cBrushes is really a handle to the old global
         * handle.  Make sure that is true.  Also lpBrushes is unused
         */
        UNREFERENCED_PARAMETER(lpBrushes);
        UserAssert(lpBrushes == NULL);
        UserAssert(cBrushes == (ULONG_PTR)gpOriginalRGBs);

        if (gpOriginalRGBs == NULL) {
            RIPMSG0(RIP_ERROR, "SetSysColorsTemp: Can not restore if not saved");
            return NULL;
        }

        /*
         * reset the global Colors
         */
        UserAssert((sizeof(abElements)/sizeof(abElements[0])) >= gcOriginalRGBs);
        for (i = 0; i < gcOriginalRGBs; i++)
            abElements[i] = i;

        NtUserSetSysColors(gcOriginalRGBs, abElements, gpOriginalRGBs, 0);

        UserLocalFree(gpOriginalRGBs);

        gpOriginalRGBs = NULL;
        gcOriginalRGBs = 0;

        return (HANDLE)TRUE;
    }

    /*
     * Make sure we aren't trying to set too many colors
     * If we allow more then COLOR_MAX change the abElements array
     */
    if (cBrushes > COLOR_MAX) {
        RIPMSG1(RIP_ERROR, "SetSysColorsTemp: trying to set too many colors %lX", cBrushes);
        return NULL;
    }

    /*
     * If we have already a saved state then don't let them save it again
     */
    if (gpOriginalRGBs != NULL) {
        RIPMSG0(RIP_ERROR, "SetSysColorsTemp: temp colors already set");
        return NULL;
    }

    /*
     * If we are here then we must be setting the new temp colors
     *
     * First save the old colors
     */
    cbRGBSize = sizeof(COLORREF) * (UINT)cBrushes;

    UserAssert(sizeof(COLORREF) == sizeof(int));
    gpOriginalRGBs = UserLocalAlloc(HEAP_ZERO_MEMORY, cbRGBSize);

    if (gpOriginalRGBs == NULL) {
        RIPMSG0(RIP_WARNING, "SetSysColorsTemp: unable to alloc temp colors buffer");
    }

    RtlCopyMemory(gpOriginalRGBs, gpsi->argbSystem, cbRGBSize);

    /*
     * Now set the new colors.
     */
    UserAssert( (sizeof(abElements)/sizeof(abElements[0])) >= cBrushes);

    for (i = 0; i < cBrushes; i++)
        abElements[i] = i;

    NtUserSetSysColors((UINT)cBrushes, abElements, lpRGBs, 0);

    gcOriginalRGBs = (UINT)cBrushes;

    return gpOriginalRGBs;
}
コード例 #7
0
ファイル: softkbd.c プロジェクト: conioh/os-design
HWND WINAPI
ImmCreateSoftKeyboard(
    UINT uType,
    HWND hOwner,
    int  x,
    int  y)
{
    static BOOL fFirstSoftKeyboard = TRUE;
    PIMEDPI     pImeDpi;
    DWORD       fdwUICaps;
    int         nWidth, nHeight;
    HKL         hCurrentKL;
    UINT        i;
    HWND        hSKWnd;
    RECT        rcWork;
    SIZE        szWork;

    if (!uType) {
        return (HWND)NULL;
    }

    if (uType >= sizeof(SoftKeyboardClassName) / sizeof(LPWSTR)) {
        return (HWND)NULL;
    }

    hCurrentKL = GetKeyboardLayout(0);

    pImeDpi = ImmLockImeDpi(hCurrentKL);
    if (pImeDpi == NULL) {
        RIPMSG1(RIP_WARNING,
              "ImmCreateSoftKeyboard, pImeDpi = NULL (hkl = 0x%x).\n", hCurrentKL);
        return (HWND)NULL;
    }

    fdwUICaps = pImeDpi->ImeInfo.fdwUICaps;
    ImmUnlockImeDpi(pImeDpi);

    if (!(fdwUICaps & UI_CAP_SOFTKBD)) {
        return (HWND)NULL;
    }

    if (fFirstSoftKeyboard) {
        if (!GetNearestMonitorSize(hOwner, &rcWork)) {
            // failed
            return NULL;
        }

        for (i = 0; i < sizeof(guScanCode) / sizeof(UINT); i++) {
            guScanCode[i] = MapVirtualKey(i, 0);
        }


        // LATER: have to consider the dynamic resolution change

        szWork.cx = rcWork.right - rcWork.left;

        UserAssert(szWork.cx > UI_MARGIN * 2);
        szWork.cy = rcWork.bottom - rcWork.top;
        UserAssert(szWork.cy > UI_MARGIN * 2);

        gptRaiseEdge.x = GetSystemMetrics(SM_CXEDGE) +
            GetSystemMetrics(SM_CXBORDER);
        gptRaiseEdge.y = GetSystemMetrics(SM_CYEDGE) +
            GetSystemMetrics(SM_CYBORDER);

        fFirstSoftKeyboard = FALSE;
    }

    if (!RegisterSoftKeyboard(uType)) {
        return (HWND)NULL;
    }

    GetSoftKeyboardDimension(uType, &nWidth, &nHeight);

    // boundry check
    if (x < 0) {
        x = 0;
    } else if (x + nWidth > szWork.cx) {
        x = szWork.cx - nWidth;
    }

    if (y < 0) {
        y = 0;
    } else if (y + nHeight > szWork.cy) {
        y = szWork.cy - nHeight;
    }

    switch (uType) {
    case SOFTKEYBOARD_TYPE_T1:
        hSKWnd = CreateWindowEx(0,
                                SoftKeyboardClassName[uType],
                                (LPCWSTR)NULL,
                                WS_POPUP|WS_DISABLED,
                                x, y, nWidth, nHeight,
                                (HWND)hOwner, (HMENU)NULL, ghInst, NULL);
        break;
    case SOFTKEYBOARD_TYPE_C1:
        hSKWnd = CreateWindowEx(WS_EX_WINDOWEDGE|WS_EX_DLGMODALFRAME,
                                SoftKeyboardClassName[uType],
                                (LPCWSTR)NULL,
                                WS_POPUP|WS_DISABLED|WS_BORDER,
                                x, y, nWidth, nHeight,
                                (HWND)hOwner, (HMENU)NULL, ghInst, NULL);
        break;
    default:
        return (HWND)NULL;
    }

    ShowWindow(hSKWnd, SW_HIDE);
    UpdateWindow(hSKWnd);

    return (hSKWnd);
}
コード例 #8
0
ファイル: fntsweep.c プロジェクト: Gaikokujin/WinNT4
VOID vMoveFileFromSystemToFontsDir(WCHAR *pwcFile)
{
    WCHAR awcTmpBuf[MAX_PATH];
    WCHAR awcTmp[MAX_PATH];
    FLONG fl;
    WCHAR *pwcTmp;

#if DBG
    BOOL  bOk;
#endif

    if (bMakePathNameW(awcTmp, pwcFile,NULL, &fl))
    {
    // If the font is in the system subdirectory we will just move it
    // to the fonts subdirectory. The path in the registry is relative
    // and we will leave it alone.

        if
        (
            (fl & (FONT_IN_SYSTEM_DIR | FONT_RELATIVE_PATH)) ==
            (FONT_IN_SYSTEM_DIR | FONT_RELATIVE_PATH)
        )
        {
        // find the bare file part, this is what will be written
        // in the registry

            pwcTmp = &awcTmp[wcslen(awcTmp) - 1];
            while ((pwcTmp >= awcTmp) && (*pwcTmp != L'\\') && (*pwcTmp != L':'))
                pwcTmp--;

            if (pwcTmp > awcTmp)
                pwcTmp++;

        // need to move the font to fonts dir, can reuse the
        // buffer on the stack to build the full destination path

            wcscpy(awcTmpBuf, gpwcFontsDir);
            lstrcatW(awcTmpBuf, L"\\");
            lstrcatW(awcTmpBuf, pwcTmp);

        // note that MoveFile should succeed, for if there was
        // a font file of the same file name in %windir%\fonts dir
        // we would not have been in this code path.

            #if DBG
                bOk =
            #endif
                MoveFileW(awcTmp, awcTmpBuf);

            RIPMSG3(RIP_VERBOSE,
                    "move %ws to %ws %s",
                    awcTmp,
                    awcTmpBuf,
                    (bOk) ? "succeeded" : "failed");
        }
        #if DBG
        else
        {
            RIPMSG2(RIP_WARNING,
                    "File %ws not in system directory, fl = 0x%lx\n",
                    awcTmp, fl);
        }
        #endif

    }
    #if DBG
    else
    {
        RIPMSG1(RIP_WARNING, "Could not locate %ws", pwcFile);
    }
    #endif
}
コード例 #9
0
ファイル: input.c プロジェクト: conioh/os-design
VOID
ImmPostMessages(
    HWND      hWnd,
    HIMC      hImc,
    INT       iNum,
    PTRANSMSG pTransMsg)
{
    INT i;
    BOOL fAnsiIME;
    PCLIENTIMC pClientImc;
    PTRANSMSG pTransMsgTemp, pTransMsgBuf = NULL;

    //
    // Check if the IME is unicode or not.
    // The message buffer contains unicode messages
    // if the IME is unicode.
    //
    pClientImc = ImmLockClientImc(hImc);
    if (pClientImc == NULL) {
        RIPMSG1(RIP_WARNING,
                "ImmPostMessages: Invalid hImc %lx.", hImc);
        return;
    }

    fAnsiIME = ! TestICF(pClientImc, IMCF_UNICODE);
    ImmUnlockClientImc(pClientImc);

    //
    // translate messages to 3.x format if the App's version is 3.x.
    //
    pTransMsgTemp = pTransMsg;
    if (GetClientInfo()->dwExpWinVer < VER40) {
        DWORD dwLangId = PRIMARYLANGID(
                                      LANGIDFROMLCID(
                                                    GetSystemDefaultLCID()));
        if ( (dwLangId == LANG_KOREAN && TransGetLevel(hWnd) == 3) ||
             dwLangId == LANG_JAPANESE ) {

            pTransMsgBuf = ImmLocalAlloc(0, iNum * sizeof(TRANSMSG));
            if (pTransMsgBuf != NULL) {
                RtlCopyMemory(pTransMsgBuf, pTransMsg, iNum * sizeof(TRANSMSG));
                iNum = WINNLSTranslateMessage(iNum,
                                              pTransMsgBuf,
                                              hImc,
                                              fAnsiIME,
                                              dwLangId );
                pTransMsgTemp = pTransMsgBuf;
            }
        }
    }

    for (i = 0; i < iNum; i++) {
        if (fAnsiIME) {
            PostMessageA(hWnd,
                    pTransMsgTemp->message,
                    pTransMsgTemp->wParam,
                    pTransMsgTemp->lParam);
        } else {
            PostMessageW(hWnd,
                    pTransMsgTemp->message,
                    pTransMsgTemp->wParam,
                    pTransMsgTemp->lParam);
        }
        pTransMsgTemp++;
    }

    if (pTransMsgBuf != NULL) {
        ImmLocalFree(pTransMsgBuf);
    }
}
コード例 #10
0
ファイル: input.c プロジェクト: conioh/os-design
/***************************************************************************\
* ImmTranslateMessage (Called from user\client\ntstubs.c\TranslateMessage())
*
* Call ImeToAsciiEx()
*
* History:
* 01-Mar-1996 TakaoK       Created
\***************************************************************************/
BOOL ImmTranslateMessage(
    HWND        hwnd,
    UINT        message,
    WPARAM      wParam,
    LPARAM      lParam)
{
    HIMC hImc;
    PINPUTCONTEXT pInputContext;
    BOOL fReturn = FALSE;
    HKL  hkl;
    PIMEDPI pImeDpi = NULL;
    PBYTE pbKeyState;
    PTRANSMSG pTransMsg;
    PTRANSMSGLIST pTransMsgList;
    DWORD dwSize;
    UINT uVKey;
    INT iNum;

    UNREFERENCED_PARAMETER(wParam);

    //
    // we're interested in only those keyboard messages.
    //
    switch (message) {
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
        break;
    default:
        return FALSE;
    }

    //
    // input context is necessary for further handling
    //
    hImc = ImmGetContext(hwnd);
    pInputContext = ImmLockIMC(hImc);
    if (pInputContext == NULL) {
        ImmReleaseContext(hwnd, hImc);
        return FALSE;
    }

    //
    // At first, handle VK_PROCESSKEY generated by IME.
    //
    if (!pInputContext->fChgMsg) {

        if ((iNum=pInputContext->dwNumMsgBuf) != 0) {

            pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf);
            if (pTransMsg != NULL) {
                ImmPostMessages(hwnd, hImc, iNum, pTransMsg);
                ImmUnlockIMCC(pInputContext->hMsgBuf);
                fReturn = TRUE;
            }

            pInputContext->dwNumMsgBuf = 0;
        }
        goto ExitITM;
    }

    pInputContext->fChgMsg = FALSE;

    //
    // retrieve the keyboard layout and IME entry points
    //
    hkl = GetKeyboardLayout( GetWindowThreadProcessId(hwnd, NULL) );
    pImeDpi = ImmLockImeDpi(hkl);
    if (pImeDpi == NULL) {
        RIPMSG1(RIP_WARNING, "ImmTranslateMessage pImeDpi is NULL(hkl=%x)", hkl);
        goto ExitITM;
    }

    pbKeyState = ImmLocalAlloc(0, 256);
    if ( pbKeyState == NULL ) {
        RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" );
        goto ExitITM;
    }

    if (!GetKeyboardState(pbKeyState)) {
        RIPMSG0(RIP_WARNING, "ImmTranslateMessage GetKeyboardState() failed" );
        ImmLocalFree( pbKeyState );
        goto ExitITM;
    }

    //
    // Translate the saved vkey into character code if needed
    //
    uVKey = pInputContext->uSavedVKey;

    if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_KBD_CHAR_FIRST) {

        if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) {
            WCHAR wcTemp;

            iNum = ToUnicode(pInputContext->uSavedVKey, // virtual-key code
                             HIWORD(lParam),            // scan code
                             pbKeyState,                // key-state array
                             &wcTemp,                   // buffer for translated key
                             1,                         // size of buffer
                             0);
            if (iNum == 1) {
                //
                // hi word            : unicode character code
                // hi byte of lo word : zero
                // lo byte of lo word : virtual key
                //
                uVKey = (uVKey & 0x00ff) | ((UINT)wcTemp << 16);
            }

        } else {
            WORD wTemp = 0;

            iNum = ToAsciiEx(pInputContext->uSavedVKey, // virtual-key code
                             HIWORD(lParam),            // scan code
                             pbKeyState,                // key-state array
                             &wTemp,                    // buffer for translated key
                             0,                         // active-menu flag
                             hkl);
            ImmAssert(iNum <= 2);
            if (iNum > 0) {
                //
                // hi word            : should be zero
                // hi byte of lo word : character code
                // lo byte of lo word : virtual key
                //
                uVKey = (uVKey & 0x00FF) | ((UINT)wTemp << 8);

                if ((BYTE)uVKey == VK_PACKET) {
                    //
                    // If ANSI IME is wide vkey aware, its ImeToAsciiEx will receive the uVKey
                    // as follows:
                    //
                    //  31            24 23                         16 15                8 7             0
                    // +----------------+-----------------------------+-------------------+---------------+
                    // | 24~31:reserved | 16~23:trailing byte(if any) | 8~15:leading byte | 0~7:VK_PACKET |
                    // +----------------+-----------------------------+-------------------+---------------+
                    //
                    ImmAssert(pImeDpi->ImeInfo.fdwProperty & IME_PROP_ACCEPT_WIDE_VKEY);
                }
                else {
                    uVKey &= 0xffff;
                }
            }
        }
    }

    dwSize = FIELD_OFFSET(TRANSMSGLIST, TransMsg)
           + TRANSMSGCOUNT * sizeof(TRANSMSG);

    pTransMsgList = (PTRANSMSGLIST)ImmLocalAlloc(0, dwSize);

    if (pTransMsgList == NULL) {
        RIPMSG0(RIP_WARNING, "ImmTranslateMessage out of memory" );
        ImmLocalFree(pbKeyState);
        goto ExitITM;
    }

    pTransMsgList->uMsgCount = TRANSMSGCOUNT;
    iNum = (*pImeDpi->pfn.ImeToAsciiEx)(uVKey,
                                        HIWORD(lParam),
                                        pbKeyState,
                                        pTransMsgList,
                                        0,
                                        hImc);

    if (iNum > TRANSMSGCOUNT) {

        //
        // The message buffer is not big enough. IME put messages
        // into hMsgBuf in the input context.
        //

        pTransMsg = (PTRANSMSG)ImmLockIMCC(pInputContext->hMsgBuf);
        if (pTransMsg != NULL) {
            ImmPostMessages(hwnd, hImc, iNum, pTransMsg);
            ImmUnlockIMCC(pInputContext->hMsgBuf);
        }

#ifdef LATER
        // Shouldn't we need this ?
        fReturn = TRUE;
#endif

    } else if (iNum > 0) {
        ImmPostMessages(hwnd, hImc, iNum, &pTransMsgList->TransMsg[0]);
        fReturn = TRUE;
    }

    ImmLocalFree(pbKeyState);
    ImmLocalFree(pTransMsgList);

ExitITM:
    ImmUnlockImeDpi(pImeDpi);
    ImmUnlockIMC(hImc);
    ImmReleaseContext(hwnd, hImc);

    return fReturn;
}
コード例 #11
0
ファイル: immime.c プロジェクト: Gaikokujin/WinNT4
BOOL LoadIME(
    PIMEINFOEX piiex,
    PIMEDPI    pImeDpi)
{
    WCHAR wszImeFile[MAX_PATH];
    BOOL  fSuccess;
    UINT  i;

    i = GetSystemDirectoryW(wszImeFile, MAX_PATH);
    wszImeFile[i] = L'\0';
    AddBackslash(wszImeFile);
    wcscat(wszImeFile, piiex->wszImeFile);

    pImeDpi->hInst = LoadLibraryW(wszImeFile);

    if (!pImeDpi->hInst) {
        RIPMSG1(RIP_WARNING, "LoadIME: LoadLibraryW(%ws) failed", wszImeFile);
        goto LoadIME_ErrOut;
    }

#define GET_IMEPROCT(x) \
    if (!(pImeDpi->pfn.##x.t = (PVOID) GetProcAddress(pImeDpi->hInst, #x))) { \
        RIPMSG1(RIP_WARNING, "LoadIME: " #x " not supported in %ws", wszImeFile);           \
        goto LoadIME_ErrOut; }

#define GET_IMEPROC(x) \
    if (!(pImeDpi->pfn.##x = (PVOID) GetProcAddress(pImeDpi->hInst, #x))) {   \
        RIPMSG1(RIP_WARNING, "LoadIME: " #x " not supported in %ws", wszImeFile);           \
        goto LoadIME_ErrOut; }

    GET_IMEPROCT(ImeInquire);
    GET_IMEPROCT(ImeConversionList);
    GET_IMEPROCT(ImeRegisterWord);
    GET_IMEPROCT(ImeUnregisterWord);
    GET_IMEPROCT(ImeGetRegisterWordStyle);
    GET_IMEPROCT(ImeEnumRegisterWord);
    GET_IMEPROC (ImeConfigure);
    GET_IMEPROC (ImeDestroy);
    GET_IMEPROC (ImeEscape);
    GET_IMEPROC (ImeProcessKey);
    GET_IMEPROC (ImeSelect);
    GET_IMEPROC (ImeSetActiveContext);
    GET_IMEPROC (ImeToAsciiEx);
    GET_IMEPROC (NotifyIME);
    GET_IMEPROC (ImeSetCompositionString);

#undef GET_IMEPROCT
#undef GET_IMEPROC

    if (!InquireIme(pImeDpi)) {
        RIPMSG0(RIP_WARNING, "LoadIME: InquireIme failed");
LoadIME_ErrOut:
        FreeLibrary(pImeDpi->hInst);
        pImeDpi->hInst = NULL;
        fSuccess = FALSE;
    }
    else {
        fSuccess = TRUE;
    }

    /*
     * Update kernel side IMEINFOEX for this keyboard layout if
     * this is its first loading.
     */
    if (piiex->fLoadFlag == IMEF_NONLOAD) {
        if (fSuccess) {
            RtlCopyMemory((PBYTE)&piiex->ImeInfo,
                          (PBYTE)&pImeDpi->ImeInfo, sizeof(IMEINFO));
            RtlCopyMemory((PBYTE)piiex->wszUIClass,
                          (PBYTE)pImeDpi->wszUIClass, sizeof(pImeDpi->wszUIClass));
            piiex->fLoadFlag = IMEF_LOADED;
        }
        else {
            piiex->fLoadFlag = IMEF_LOADERROR;
        }
        NtUserSetImeInfoEx(piiex);
    }

    return fSuccess;
}
コード例 #12
0
ファイル: immime.c プロジェクト: Gaikokujin/WinNT4
BOOL WINAPI ImmConfigureIMEW(
    HKL    hKL,
    HWND   hWnd,
    DWORD  dwMode,
    LPVOID lpData)
{
    PWND    pWnd;
    PIMEDPI pImeDpi;
    BOOL    fRet = FALSE;

    if ((pWnd = ValidateHwnd(hWnd)) == (PWND)NULL) {
        RIPMSG1(RIP_WARNING,
              "ImmConfigureIMEA: invalid window handle %x", hWnd);
        return FALSE;
    }

    if (!TestWindowProcess(pWnd)) {
        RIPMSG1(RIP_WARNING,
              "ImmConfigureIMEA: hWnd=%lx belongs to different process!", hWnd);
        return FALSE;
    }

    pImeDpi = FindOrLoadImeDpi(hKL);
    if (pImeDpi == NULL) {
        RIPMSG0(RIP_WARNING, "ImmConfigureIMEA: no pImeDpi entry.");
        return FALSE;
    }

    if ((pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) || lpData == NULL) {
        /*
         * Doesn't need A/W conversion. Calls directly to IME to
         * bring up the configuration dialogbox.
         */
        fRet = (*pImeDpi->pfn.ImeConfigure)(hKL, hWnd, dwMode, lpData);
        ImmUnlockImeDpi(pImeDpi);
        return fRet;
    }

    /*
     * Unicode caller, ANSI IME. Needs A/W conversion on lpData when
     * dwMode == IME_CONFIG_REGISTERWORD. In this case, lpData points
     * to a structure of REGISTERWORDW.
     */
    switch (dwMode) {
    case IME_CONFIG_REGISTERWORD:
        {
            LPREGISTERWORDW lpRegisterWordW;
            REGISTERWORDA   RegisterWordA;
            LPVOID          lpBuffer;
            ULONG           cbBuffer;
            BOOL            bUDC;
            INT             i;

            lpRegisterWordW = (LPREGISTERWORDW)lpData;
            cbBuffer = 0;
            lpBuffer = NULL;

            if (lpRegisterWordW->lpReading != NULL)
                cbBuffer += wcslen(lpRegisterWordW->lpReading) + 1;

            if (lpRegisterWordW->lpWord != NULL)
                cbBuffer += wcslen(lpRegisterWordW->lpWord) + 1;

            if (cbBuffer != 0) {
                cbBuffer *= sizeof(WCHAR);
                if ((lpBuffer = ImmLocalAlloc(0, cbBuffer)) == NULL) {
                    RIPMSG0(RIP_WARNING, "ImmConfigureIMEW: memory failure.");
                    break;
                }
            }

            if (lpRegisterWordW->lpReading != NULL) {
                RegisterWordA.lpReading = lpBuffer;
                i = WideCharToMultiByte( CP_ACP,
                                        (DWORD)0,
                                        (LPWSTR)lpRegisterWordW->lpReading,
                                        (INT)wcslen(lpRegisterWordW->lpReading),
                                        (LPSTR)RegisterWordA.lpReading,
                                        (INT)cbBuffer,
                                        (LPSTR)NULL,
                                        (LPBOOL)&bUDC);
                RegisterWordA.lpReading[i] = '\0';
                cbBuffer -= (i * sizeof(CHAR));
            }
            else {
                RegisterWordA.lpReading = NULL;
            }

            if (lpRegisterWordW->lpWord != NULL) {
                if (RegisterWordA.lpReading != NULL)
                    RegisterWordA.lpWord = &RegisterWordA.lpReading[i+1];
                else
                    RegisterWordA.lpWord = lpBuffer;
                i = WideCharToMultiByte( CP_ACP,
                                        (DWORD)0,
                                        (LPWSTR)lpRegisterWordW->lpWord,
                                        (INT)wcslen(lpRegisterWordW->lpWord),
                                        (LPSTR)RegisterWordA.lpWord,
                                        (INT)cbBuffer,
                                        (LPSTR)NULL,
                                        (LPBOOL)&bUDC);
                RegisterWordA.lpWord[i] = '\0';
            }
            else
                RegisterWordA.lpWord = NULL;

            fRet = ImmConfigureIMEA(hKL, hWnd, dwMode, &RegisterWordA);

            if (lpBuffer != NULL)
                ImmLocalFree(lpBuffer);

            break;
        }
    default:
        fRet = ImmConfigureIMEA(hKL, hWnd, dwMode, lpData);
        break;
    }

    ImmUnlockImeDpi(pImeDpi);

    return fRet;
}
コード例 #13
0
ファイル: immime.c プロジェクト: Gaikokujin/WinNT4
PIMEDPI FindOrLoadImeDpi(
    HKL hKL)
{
    PIMEDPI        pImeDpi, pTmpImeDpi;
    IMEINFOEX      iiex;

    /*
     * Non IME based keyboard layout doesn't have IMEDPI.
     */
    if (!IS_IME_KBDLAYOUT(hKL))
        return (PIMEDPI)NULL;

    pImeDpi = ImmLockImeDpi(hKL);

    if (pImeDpi == NULL) {
        /*
         * This process hasn't load up the specified IME based layout.
         * Query the IME information and load it up now.
         */
        if (!ImmGetImeInfoEx(&iiex, ImeInfoExKeyboardLayout, &hKL)) {
            RIPMSG1(RIP_WARNING,
                  "FindOrLoadImeDpi: ImmGetImeInfoEx(%lx) failed", hKL);
            return NULL;
        }

        /*
         * Win95 behaviour: If there was an IME load error for this layout,
         * further attempt to load the same IME layout will be rejected.
         */
        if (iiex.fLoadFlag == IMEF_LOADERROR)
            return NULL;

        /*
         * Allocate a new IMEDPI for this layout.
         */
        pImeDpi = (PIMEDPI)ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(IMEDPI));
        if (pImeDpi == NULL)
            return NULL;

        if (!LoadIME(&iiex, pImeDpi)) {
            LocalFree(pImeDpi);
            return NULL;
        }

        pImeDpi->hKL = hKL;
        pImeDpi->cLock++;

        /*
         * Link in the newly allocated entry.
         */
        RtlEnterCriticalSection(&gcsImeDpi);

        /*
         * Serach the gpImeDpi list again and discard this
         * pImeDpi if other thread has updated the list for
         * the same layout while we leave the critical section.
         */
        pTmpImeDpi = ImmLockImeDpi(hKL);

        if (pTmpImeDpi == NULL) {
            /*
             * Update the global list for this new pImeDpi entry.
             */
            pImeDpi->pNext = gpImeDpi;
            gpImeDpi = pImeDpi;
            RtlLeaveCriticalSection(&gcsImeDpi);
        }
        else {
            /*
             * The same IME has been loaded, discard this extra entry.
             */
            RtlLeaveCriticalSection(&gcsImeDpi);
            UnloadIME(pImeDpi, FALSE);
            ImmLocalFree(pImeDpi);
            pImeDpi = pTmpImeDpi;
        }
    }

    return pImeDpi;
}
コード例 #14
0
ファイル: immime.c プロジェクト: Gaikokujin/WinNT4
BOOL InquireIme(
    PIMEDPI pImeDpi)
{
    WNDCLASS    wc;
    WCHAR       wszClassName[IM_UI_CLASS_SIZE];
    PIMEINFO    pImeInfo = &pImeDpi->ImeInfo;

    (*pImeDpi->pfn.ImeInquire.w)(pImeInfo, (PVOID)wszClassName, NULL);

    /*
     * parameter checking for each fields.
     */
    if (pImeInfo->dwPrivateDataSize == 0)
        pImeInfo->dwPrivateDataSize = sizeof(UINT);

    if (pImeInfo->fdwProperty & ~(IME_PROP_ALL)) {
        RIPMSG0(RIP_WARNING, "wrong property");
        return FALSE;
    }

    if (pImeInfo->fdwConversionCaps & ~(IME_CMODE_ALL)) {
        RIPMSG0(RIP_WARNING, "wrong conversion capabilities");
        return FALSE;
    }

    if (pImeInfo->fdwSentenceCaps & ~(IME_SMODE_ALL)) {
        RIPMSG0(RIP_WARNING, "wrong sentence capabilities");
        return FALSE;
    }

    if (pImeInfo->fdwUICaps & ~(UI_CAP_ALL)) {
        RIPMSG0(RIP_WARNING, "wrong UI capabilities");
        return FALSE;
    }

    if (pImeInfo->fdwSCSCaps & ~(SCS_CAP_ALL)) {
        RIPMSG0(RIP_WARNING, "wrong set comp string capabilities");
        return FALSE;
    }

    if (pImeInfo->fdwSelectCaps & ~(SELECT_CAP_ALL)) {
        RIPMSG0(RIP_WARNING, "wrong select capabilities");
        return FALSE;
    }

    if (!(pImeInfo->fdwProperty & IME_PROP_UNICODE)) {
        ANSI_STRING     AnsiString;
        UNICODE_STRING  UnicodeString;

        RtlInitAnsiString(&AnsiString, (LPSTR)wszClassName);
        UnicodeString.MaximumLength = (SHORT)sizeof(pImeDpi->wszUIClass);
        UnicodeString.Buffer = pImeDpi->wszUIClass;

        if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
                                                     &AnsiString,
                                                     FALSE))) {
            return FALSE;
        }
    }
    else {
        RtlCopyMemory(pImeDpi->wszUIClass, wszClassName, sizeof(wszClassName));
        pImeDpi->wszUIClass[IM_UI_CLASS_SIZE-1] = L'\0';
    }

    if (!GetClassInfoW((HINSTANCE)pImeDpi->hInst, pImeDpi->wszUIClass, &wc)) {
        RIPMSG1(RIP_WARNING, "UI class (%ws) not found in this IME", pImeDpi->wszUIClass);
        return FALSE;
    } else if (wc.cbWndExtra < sizeof(DWORD) * 2) {
        RIPMSG0(RIP_WARNING, "UI class cbWndExtra problem");
        return FALSE;
    }

    return TRUE;
}
コード例 #15
0
ファイル: tooltips.c プロジェクト: conioh/os-design
void xxxTrackMouseMove(PWND pwnd, int htEx, UINT message)
{
    BOOL fNewpwndTrack;
    DWORD dwDTCancel = 0;
    TL tlpwnd;
    LPWSTR pstr;
    PDESKTOP pdesk = PtiCurrent()->rpdesk;
    PTHREADINFO ptiTrack;


#if DBG
    /*
     * Let's warn if this function gets reenterd so we can make sure
     * nothing bad will follow. This should be a rare situation.
     * Look in gptiReEntered to find out who is already here.
     */
    static UINT gcReEntered = 0;
    static PTHREADINFO gptiReEntered;
    if(gcReEntered++ != 0){
      RIPMSG2(RIP_WARNING, "Reentered xxxTrackMouseMove; previous thread was %#p, current thread is %#p", gptiReEntered, PtiCurrent());
    }
    gptiReEntered = PtiCurrent();

    CheckLock(pwnd);

    /*
     * We must be on an interactive window station.
     */
    if (pdesk->rpwinstaParent != NULL &&
            pdesk->rpwinstaParent->dwWSF_Flags & WSF_NOIO) {
        RIPMSG0(RIP_ERROR, "Can't use tooltips on non-interactive winsta");
    }

     {
        static POINT pt = {0, 0};

#ifdef UNDONE
        /*
         * We might have taken a guess on the hit test (see FindNCHitEx)
         *  so if we're at the same point and same window, something
         *  might be fishy
         */
        if ((pt.x == gpsi->ptCursor.x)
                    && (pt.y == gpsi->ptCursor.y)
                    && (pdesk->spwndTrack == pwnd)) {
            RIPMSG1(RIP_WARNING, "xxxTrackMouseMove: Same point & window. %#p", pwnd);
        }
#endif

        /*
         * Something is supposed to have changed or we're wasting time
         */
        UserAssert((pt.x != gpsi->ptCursor.x)
                    || (pt.y != gpsi->ptCursor.y)
                    || (pdesk->spwndTrack != pwnd)
                    || (pdesk->htEx != htEx)
                    || (message != WM_MOUSEMOVE));
        /*
         * Remember last tracked point
         */
        pt = gpsi->ptCursor;
     }
    /*
     * pwnd is supposed to be on the current thread and queue
     */
    UserAssert(PtiCurrent() == GETPTI(pwnd));
    UserAssert(PtiCurrent()->pq == GETPTI(pwnd)->pq);
#endif

    /*
     * Have we switched windows?
     */
    fNewpwndTrack = (pdesk->spwndTrack != pwnd);
    /*
     * If no tracking is taking place, just go set the new
     *  tracking state
     */
    if (!(pdesk->dwDTFlags & DF_MOUSEMOVETRK)) {
        goto SetNewState;
    }
    /*
     * Potentially while we leave the critical section below in
     * xxxCancelMouseMoveTracking, spwndTrack could be destroyed and unlocked
     * and then we go and create the tooltip. This would mean that
     * DF_TOOLTIPACTIVE (part of DF_MOUSEMOVETRK test above) would be set,
     * but pdesk->spwndTrack would be NULL and we can AV dereferencing
     * pdesk->spwndTrack below. Prevent this by making the check here.
     */
    if (pdesk->spwndTrack == NULL) {
        goto SetNewState;
    }

    /*
     * Nuke hottracking and deactivate tooltip state, if any.
     * Do it sychronously if we're tracking on the current queue;
     *  Otherwise, post an event and let it happen later.
     */
    ptiTrack = GETPTI(pdesk->spwndTrack);
    if  (PtiCurrent()->pq == ptiTrack->pq) {
        dwDTCancel |= DF_HOTTRACKING;
    } else if (pdesk->dwDTFlags & (DF_HOTTRACKING | DF_TOOLTIPACTIVE)) {
        PostEventMessage(ptiTrack, ptiTrack->pq,
                        QEVENT_CANCELMOUSEMOVETRK,
                        pdesk->spwndTrack,
                        pdesk->dwDTFlags,
                        pdesk->htEx, DF_HOTTRACKING);
       /*
        * Paranoid assertion. If we're switching queues, we must
        *  be switching windows. Did we just go through
        *  ReattachThreads?
        */
        UserAssert(pwnd != pdesk->spwndTrack);
        pdesk->dwDTFlags &= ~(DF_HOTTRACKING | DF_TOOLTIPACTIVE);
    }
    /*
     * If we're on the client area or the user clicked,
     *  nuke the tooltip (if any).
     * Since we might want to re-show the tooltip, we don't nuke it
     *  now if we swichted windows (we'll nuke it later if needed)
     */
    if ((htEx == HTCLIENT) || (message != WM_MOUSEMOVE)) {
        dwDTCancel |= DF_TOOLTIPACTIVE;
    }
    /*
     * If we switched windows or crossed client/nonclinet boundaries,
     *  end track mouse leave/hover.
     */
    if (fNewpwndTrack || ((pdesk->htEx == HTCLIENT) ^ (htEx == HTCLIENT))) {
        dwDTCancel |= DF_TRACKMOUSEEVENT;
    }
    /*
     * Cancel whatever is active and needs to go away
     */
    ThreadLockAlways(pdesk->spwndTrack, &tlpwnd);
    xxxCancelMouseMoveTracking(pdesk->dwDTFlags,
                           pdesk->spwndTrack,
                           pdesk->htEx,
                           dwDTCancel);
    ThreadUnlock(&tlpwnd);
    pdesk->dwDTFlags &= ~dwDTCancel;



SetNewState:
    /*
     * Hottracking/tooltip on mouse move if on NC hitest and enabled
     */
    if ((htEx != HTCLIENT) && (message == WM_MOUSEMOVE) && TestEffectUP(HOTTRACKING)) {
        /*
         * Hottrack the new hit test area
         */
        if (xxxHotTrack(pwnd, htEx, TRUE)) {
            pdesk->dwDTFlags |= DF_HOTTRACKING;
        }

        /*
         * Remove/set the tool tip.
         * We always do this synchronously because it doesn't mess
         *  with pwnd's or spwnTrack's queue
         */
        if ((pstr = IsTooltipHittest(pwnd, LOWORD(htEx))) != NULL) {
            PTOOLTIPWND pttwnd = (PTOOLTIPWND)pdesk->spwndTooltip;
            ThreadLockAlways(pttwnd, &tlpwnd);
            xxxCreateTooltip(pttwnd, pstr);
            ThreadUnlock(&tlpwnd);
            pdesk->dwDTFlags |= DF_TOOLTIP;
        } else  {
            PTOOLTIPWND pttwnd = (PTOOLTIPWND)pdesk->spwndTooltip;
            ThreadLockAlways(pttwnd, &tlpwnd);
            xxxResetTooltip(pttwnd);
            ThreadUnlock(&tlpwnd);
        }
    } /* if (htEx != HTCLIENT) */


    ValidateThreadLocks(NULL, PtiCurrent()->ptl, (ULONG_PTR)&pwnd, TRUE);

    /*
     * Update new track window if needed.
     */
    if (fNewpwndTrack) {
        PWND pwndActivate;

         Lock(&pdesk->spwndTrack, pwnd);
        /*
         * Active window tracking.
         * If there is non-zero timeout, get the window we're supposed to activate
         *  and set the timer. Otherwise, set the queue flag so
         *  xxxActiveWindowTracking can do its thing.
         */
         if ((message == WM_MOUSEMOVE) && TestUP(ACTIVEWINDOWTRACKING)) {
             if (UP(ACTIVEWNDTRKTIMEOUT) != 0) {
                 pwndActivate = GetActiveTrackPwnd(pwnd, NULL);
                 if (pwndActivate != NULL) {
                     InternalSetTimer(pwndActivate, IDSYS_WNDTRACKING,
                                     UP(ACTIVEWNDTRKTIMEOUT),
                                     xxxSystemTimerProc, TMRF_SYSTEM);
                 }
             } else {
                 PtiCurrent()->pq->QF_flags |= QF_ACTIVEWNDTRACKING;
             } /* if (TestUP(ACTIVEWNDTRKZORDER)) */
         } /* if (TestUP(ACTIVEWINDOWTRACKING)) */

    }

    /*
     * Save new hit test code
     */
    pdesk->htEx = htEx;

#if DBG
    --gcReEntered;
#endif
}
コード例 #16
0
ファイル: fekbd.c プロジェクト: conioh/os-design
VOID NlsKbdInitializePerSystem(VOID)
{
    RTL_QUERY_REGISTRY_TABLE QueryTable[4];

    UNICODE_STRING EndString, HelpString;
    UNICODE_STRING YesString, NoString;
    UNICODE_STRING HomeString, ClearString;

    UNICODE_STRING HelpKeyString;
    UNICODE_STRING KanaHelpString;
    UNICODE_STRING ClearKeyString;

    NTSTATUS status;

    //
    // Set default VK_DBE_xxx status.
    //
    //
    // AlphaNumeric input mode.
    //
    NlsSetKeyStateToggle(VK_DBE_ALPHANUMERIC);
    //
    // Single byte character input mode.
    //
    NlsSetKeyStateToggle(VK_DBE_SBCSCHAR);
    //
    // No roman input mode.
    //
    NlsSetKeyStateToggle(VK_DBE_NOROMAN);
    //
    // No code input mode.
    //
    NlsSetKeyStateToggle(VK_DBE_NOCODEINPUT);

    //
    // From Here, below code is for compatibility for Windows NT 3.xx
    // for NEC PC-9800 verion.
    //

    //
    // Initialize default strings.
    //
    RtlInitUnicodeString(&EndString, L"end");
    RtlInitUnicodeString(&HelpString,L"help");

    RtlInitUnicodeString(&YesString,L"yes");
    RtlInitUnicodeString(&NoString, L"no");

    RtlInitUnicodeString(&HomeString, L"home");
    RtlInitUnicodeString(&ClearString,L"clear");

    //
    // Initialize recieve buffer.
    //
    RtlInitUnicodeString(&HelpKeyString,NULL);
    RtlInitUnicodeString(&KanaHelpString,NULL);
    RtlInitUnicodeString(&ClearKeyString,NULL);

    //
    // Initalize query tables.
    //
    // ValueName : "helpkey"
    // ValueData : if "end" VK_END, otherwise VK_HELP
    //
    QueryTable[0].QueryRoutine = NULL;
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
    QueryTable[0].Name = (PWSTR) L"helpkey",
    QueryTable[0].EntryContext = (PVOID) &HelpKeyString;
    QueryTable[0].DefaultType = REG_SZ;
    QueryTable[0].DefaultData = &EndString;
    QueryTable[0].DefaultLength = 0;

    //
    // ValueName : "KanaHelpKey"
    // ValueData : if "yes" if kana on switch VK_HELP and VK_END
    //
    QueryTable[1].QueryRoutine = NULL;
    QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
    QueryTable[1].Name = (PWSTR) L"KanaHelpKey",
    QueryTable[1].EntryContext = (PVOID) &KanaHelpString;
    QueryTable[1].DefaultType = REG_SZ;
    QueryTable[1].DefaultData = &YesString;
    QueryTable[1].DefaultLength = 0;

    //
    // ValueName : "clrkey"
    // ValueData : if "home" VK_HOME, otherwise VK_CLEAR
    //
    QueryTable[2].QueryRoutine = NULL;
    QueryTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
    QueryTable[2].Name = (PWSTR) L"clrkey",
    QueryTable[2].EntryContext = (PVOID) &ClearKeyString;
    QueryTable[2].DefaultType = REG_SZ;
    QueryTable[2].DefaultData = &HomeString;
    QueryTable[2].DefaultLength = 0;

    QueryTable[3].QueryRoutine = NULL;
    QueryTable[3].Flags = 0;
    QueryTable[3].Name = NULL;

    status = RtlQueryRegistryValues(
                 RTL_REGISTRY_WINDOWS_NT,
                 NLSKBD_CONFIG_PATH,
                 QueryTable, NULL, NULL);

    if (!NT_SUCCESS(status)) {
        RIPMSG1(RIP_WARNING, "FEKBD:RtlQueryRegistryValues fails (%x)\n", status);
        return;
    }

    if (RtlEqualUnicodeString(&HelpKeyString,&HelpString,TRUE)) {
        /*
         * Generate VK_HELP, when NLSKBD_HELP_OR_END is called.
         */
        fNlsKbdConfiguration &= ~GEN_VK_END;
    }

    if (RtlEqualUnicodeString(&KanaHelpString,&NoString,TRUE)) {
        /*
         * In case of "yes":
         * If 'kana' is on, when NLSKBD_HELP_OR_END is called, switch VK_END and VK_HELP.
         * Else, in case of "no":
         * Doesn't generate by 'kana' toggle state.
         */
        fNlsKbdConfiguration &= ~GEN_KANA_AWARE;
    }

    if (RtlEqualUnicodeString(&ClearKeyString,&ClearString,TRUE)) {
        /*
         * Generate VK_CLEAR, when KBDNLS_HOME_OR_CLEAR is called.
         */
        fNlsKbdConfiguration &= ~GEN_VK_HOME;
    }

    return;
}
コード例 #17
0
ファイル: dtbitmap.c プロジェクト: conioh/os-design
VOID
GetVersionInfo(
    BOOL Verbose
    )
{
    WCHAR          NameBuffer[MAXVERSIONBUFFER];
    WCHAR          Title1[128];
    WCHAR          Title2[128];
    WCHAR          wszPID[MAXVERSIONSTRING];
    WCHAR          wszPro[MAXVERSIONSTRING];
    WCHAR          wszSrv[MAXVERSIONSTRING];
    WCHAR          wszPBuild[MAXVERSIONSTRING];
    WCHAR          wszEvaluation[MAXVERSIONSTRING];
    UNICODE_STRING UserBuildString;
    UNICODE_STRING UserTypeString;
    UNICODE_STRING UserCSDString;
    NTSTATUS       Status;


    RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[] = {

        {NULL,
         RTL_QUERY_REGISTRY_DIRECT,
         L"CurrentBuildNumber",
         &UserBuildString,
         REG_NONE,
         NULL,
         0},

        {NULL,
         RTL_QUERY_REGISTRY_DIRECT,
         L"CurrentType",
         &UserTypeString,
         REG_NONE,
         NULL,
         0},

        {NULL,
         RTL_QUERY_REGISTRY_DIRECT,
         L"CSDVersion",
         &UserCSDString,
         REG_NONE,
         NULL,
         0},

        {NULL,
         0,
         NULL,
         NULL,
         REG_NONE,
         NULL,
         0}
    };

    UserBuildString.Buffer          = &NameBuffer[OFFSET_BLDSTRING];
    UserBuildString.Length          = 0;
    UserBuildString.MaximumLength   = MAXVERSIONSTRING * sizeof(WCHAR);

    UserTypeString.Buffer           = &NameBuffer[OFFSET_TYPSTRING];
    UserTypeString.Length           = 0;
    UserTypeString.MaximumLength    = MAXVERSIONSTRING * sizeof(WCHAR);

    UserCSDString.Buffer            = &NameBuffer[OFFSET_CSDSTRING];
    UserCSDString.Length            = 0;
    UserCSDString.MaximumLength     = MAXVERSIONSTRING * sizeof(WCHAR);

    Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
                                    L"",
                                    BaseServerRegistryConfigurationTable,
                                    NULL,
                                    NULL);

    if (!NT_SUCCESS(Status)) {
        RIPMSG1(RIP_WARNING, "GetVersionInfo failed with status %x", Status);
        return;
    }

    ServerLoadString( hModuleWin, STR_DTBS_PRODUCTID, wszPID, ARRAY_SIZE(wszPID) );
    ServerLoadString( hModuleWin, STR_DTBS_PRODUCTPRO, wszPro, ARRAY_SIZE(wszPro) );
    ServerLoadString( hModuleWin, STR_DTBS_PRODUCTSRV, wszSrv, ARRAY_SIZE(wszSrv) );
    ServerLoadString( hModuleWin, STR_DTBS_PRODUCTBUILD, wszPBuild, ARRAY_SIZE(wszPBuild) );

    /*
     * Write out Debugging Version message.
     */

    /*
     * Bug 280256 - joejo
     * Create new desktop build information strings
     */
    swprintf(
        wszProductName,
        wszPID,
        ((USER_SHARED_DATA->NtProductType == NtProductWinNt) ? wszPro : wszSrv)
        );

    
    if (gfUnsignedDrivers) {
        /* This takes precedence */
        ServerLoadString( hModuleWin, STR_TESTINGONLY, wszEvaluation, ARRAY_SIZE(wszEvaluation) );
    } else if (USER_SHARED_DATA->SystemExpirationDate.QuadPart) {
        ServerLoadString(hModuleWin, STR_DTBS_EVALUATION, wszEvaluation,
                ARRAY_SIZE(wszEvaluation));
    } else {
        wszEvaluation[0] = '\0';
    }

    swprintf(
        wszProductBuild,
        wszPBuild,
        wszEvaluation,
        UserBuildString.Buffer
        );

    if (Verbose) {

        ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE1, Title1, ARRAY_SIZE(Title1) );
        ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE2, Title2, ARRAY_SIZE(Title2) );

        swprintf(
            wszT,
            UserCSDString.Length == 0 ? Title1 : Title2,
            UserBuildString.Buffer,
            UserCSDString.Buffer,
            USER_SHARED_DATA->NtSystemRoot
            );

    } else {
        PWSTR s = wcsrchr( UserTypeString.Buffer, L' ' );
        if (s) {
            s += 1;
        } else {
            s = UserTypeString.Buffer;
        }

        ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE3, Title1, ARRAY_SIZE(Title1) );
        ServerLoadString( hModuleWin, STR_SAFEMODE_TITLE4, Title2, ARRAY_SIZE(Title2) );

        swprintf(
            wszT,
            UserCSDString.Length == 0 ? Title1 : Title2,
            UserBuildString.Buffer,
            UserCSDString.Buffer,
            s
            );
    }
}
コード例 #18
0
ファイル: chartran.c プロジェクト: conioh/os-design
BOOL RtlWCSMessageWParamCharToMB(DWORD msg, WPARAM *pWParam)
{
    DWORD dwAnsi;
    NTSTATUS Status;
    WORD CodePage;
    int nbWch;

#ifdef FE_SB // RtlWCSMessageWParamCharToMB()
    //
    // Format of *pWParam here...
    //
    // LOWORD(*pWParam) = Unicode CodePoint...
    // HIWORD(*pWParam) = Has some information for DBCS messaging
    //                    (ex. WPARAM_IR_DBCSCHAR)
    //
    // Then we need to convert ONLY loword of wParam to Unicode...
    //
#endif // FE_SB
#ifndef FE_SB
    // NtBug #3135 (Closed 02/04/93)
    // Publisher Posts WM_CHAR messages with wParam > 0xFF (not a valid ANSI char)!
    //
    // It does this to disable TranslateAccelerator for that char.
    // MSPub's winproc must get the non-ANSI 'character' value, so PostMessage must
    // translate *two* characters of wParam for character messages, and PeekMessage
    // must translate *two* Unicode chars of wParam for ANSI app.
#endif

    /*
     * Only these messages have CHARs: others are passed through
     */

    switch(msg) {
#ifdef FE_IME // RtlWCSMessageWParamCharToMB()
    case WM_IME_CHAR:
    case WM_IME_COMPOSITION:
#endif // FE_IME
    case WM_CHAR:
    case WM_CHARTOITEM:
    case EM_SETPASSWORDCHAR:
    case WM_DEADCHAR:
    case WM_SYSCHAR:
    case WM_SYSDEADCHAR:
    case WM_MENUCHAR:

        CodePage = THREAD_CODEPAGE();
        dwAnsi = 0;

        nbWch = IS_DBCS_ENABLED() ? 1 * sizeof(WCHAR) : 2 * sizeof(WCHAR);

        if (IS_ACP(CodePage)) {
            // HACK HACK HACK HACK (for NtBug #3135)
            // to allow applications that store data in high word of wParam
            // Jan/06/96 hiroyama
            Status = RtlUnicodeToMultiByteN((LPSTR)&dwAnsi, sizeof(dwAnsi),
                    NULL, (LPWSTR)pWParam, nbWch);
            if (!NT_SUCCESS(Status)) {
                // LATER IanJa: returning FALSE makes GetMessage fail, which
                // terminates the app.  We should use some default 'bad character'
                // I use 0x00 for now.
                *pWParam = 0x00;
                return TRUE;
            }
        } else {
            int cwch;
            // assuming little endian
#ifdef _USERK_
            cwch = EngWideCharToMultiByte(CodePage,
                    (LPWSTR)pWParam, nbWch,
                    (LPSTR)&dwAnsi, sizeof(dwAnsi));
#else
            cwch = WideCharToMultiByte(CodePage, 0,
                    (LPCWSTR)pWParam, nbWch / sizeof(WCHAR),
                    (LPSTR)&dwAnsi, sizeof(dwAnsi), NULL, NULL);
#endif // _USERK_
            // KdPrint(("0x%04x -> 0x%02x (%d)\n", *pWParam, dwAnsi, CodePage));
            if (cwch == 0) {
                *pWParam = 0x00;
                return TRUE;
            }
        }
        if (IS_DBCS_ENABLED()) {
            WORD wAnsi = LOWORD(dwAnsi);
            //
            // From:
            //   HIBYTE(wAnsi)            = Dbcs TrailingByte.
            //   LOBYTE(wAnsi)            = Dbcs LeadingByte or Sbcs character.
            //
            // To:
            //   HIWORD(*pWParam)         = Original Data (information for DBCS messgaing).
            //   HIBYTE(LOWORD(*pWParam)) = Dbcs LeadingByte Byte.
            //   LOBYTE(LOWORD(*pWParam)) = Dbcs TrailingByte or Sbcs character.
            //
            if (IS_DBCS_MESSAGE(wAnsi)) {
                //
                // It's a DBCS character.
                //
                *pWParam = MAKEWPARAM(MAKEWORD(HIBYTE(wAnsi),LOBYTE(wAnsi)),HIWORD(*pWParam));
            } else {
                //
                // It's a SBCS character.
                //
                *pWParam = MAKEWPARAM(MAKEWORD(LOBYTE(wAnsi),0),0);
            }
        } else {
#if DBG
            if ((dwAnsi == 0) || (dwAnsi > 0xFF)) {
                RIPMSG1(RIP_VERBOSE, "msgW -> msgA: char = 0x%.4lX\n", dwAnsi);
            }
#endif
            *pWParam = dwAnsi;
        }
        break;
    }

    return TRUE;
}
コード例 #19
0
ファイル: chartran.c プロジェクト: conioh/os-design
BOOL RtlMBMessageWParamCharToWCS(DWORD msg, WPARAM *pWParam)
{
    DWORD dwUni;
    NTSTATUS Status;
    // FE_SB    (RtlMBMessageWParamCharToWCS)
    BOOL  bWmCrIrDbcsChar = FALSE;
    WORD  wAnsi = LOWORD(*pWParam);
    // end FE_SB    (RtlMBMessageWParamCharToWCS)
    WORD CodePage = THREAD_CODEPAGE();

    /*
     * Only these messages have CHARs: others are passed through
     */

    switch(msg) {
    // FE_SB    (RtlMBMessageWParamCharToWCS)
    case WM_CHAR:
        //
        // WM_CHAR's wParam format for WM_IME_REPORT:IR_DBCSCHAR
        //
        if (IS_DBCS_ENABLED() && (*pWParam & WMCR_IR_DBCSCHAR)) {
            //
            // Mark this message is sent as IR_DBCSCHAR format.
            //
            bWmCrIrDbcsChar = TRUE;
        }

        //
        // Fall through....
        //
#ifdef FE_IME
    case WM_IME_CHAR:
    case WM_IME_COMPOSITION:
        //
        // We need to re-align for Unicode convertsion..
        // WM_CHAR/WM_IME_CHAR/WM_IME_COMPOSITION's wParam format :
        //
        // ReAlign IR_DBCS char format to regular sequence.
        //
        // From:
        //
        //  HIWORD(wParam)         = 0;
        //  HIBYTE(LOWORD(wParam)) = DBCS LeadingByte.
        //  LOBYTE(LOWORD(wParan)) = DBCS TrailingByte or SBCS character.
        //
        // To:
        //  HIWORD(wParam)         = 0;
        //  HIBYTE(LOWORD(wParam)) = DBCS TrailingByte.
        //  LOBYTE(LOWORD(wParam)) = DBCS LeadingByte or SBCS character.
        //
        if (IS_DBCS_ENABLED()) {
            *pWParam = MAKE_WPARAM_DBCSCHAR(wAnsi);
        }
#endif
        //
        // Fall through...
        //
        // end FE_SB    (RtlMBMessageWParamCharToWCS)
    case WM_CHARTOITEM:
    case EM_SETPASSWORDCHAR:
    case WM_DEADCHAR:
    case WM_SYSCHAR:
    case WM_SYSDEADCHAR:
    case WM_MENUCHAR:

        dwUni = 0;

        if (IS_ACP(CodePage)) {
            Status = RtlMultiByteToUnicodeN((LPWSTR)&dwUni, sizeof(dwUni),
                    NULL, (LPSTR)pWParam, 2 * sizeof(CHAR));
            if (!NT_SUCCESS(Status))
                return FALSE;
        } else {
            int cwch;
#ifdef _USERK_
            cwch = EngMultiByteToWideChar(CodePage,
                    (LPWSTR)&dwUni, sizeof(dwUni),
                    (LPSTR)pWParam, 2);
#else
            cwch = MultiByteToWideChar(CodePage, 0,
                    (LPSTR)pWParam, 2,
                    (LPWSTR)&dwUni, sizeof(dwUni) / sizeof(WCHAR));
#endif // _USERK_
            // KdPrint(("0x%02x -> 0x%04x (%d)\n", *pWParam, dwUni, CodePage));
            if (cwch == 0) {
                return FALSE;
            }
        }

        // FE_SB    (RtlMBMessageWParamCharToWCS)
        //
        // if this character is sent for WM_IME_REPORT:IR_DBCSCHAR, we mark it.
        //
        if (bWmCrIrDbcsChar)
            dwUni |= WMCR_IR_DBCSCHAR;
        // else FE_SB (RtlMBMessageWParamCharToWCS)
#if DBG
        if ((dwUni == 0) || (dwUni > 0xFF)) {
            RIPMSG1(RIP_VERBOSE, "msgA -> msgW: wchar = 0x%lX\n", dwUni);
        }
#endif
        // end FE_SB
        *pWParam = dwUni;
        break;
    }

    return TRUE;
}
コード例 #20
0
ファイル: fntsweep.c プロジェクト: Gaikokujin/WinNT4
VOID vProcessFontEntry(
    HKEY   hkey,
    WCHAR *pwcValueName,
    WCHAR *pwcFileName
)
{
    BOOL  bFot = FALSE;
    WCHAR awcTTF[MAX_PATH];
    WCHAR awcTmpBuf[MAX_PATH];
    WCHAR *pwcTTF;
    FLONG fl, fl2;
    FLONG flEmbed;
    DWORD dwPidTid;

    if (bCheckFontEntry(pwcValueName, EXT_TRUETYPE))
    {
    // This is a tt entry, either .fot or .ttf

        if (bFot = bCheckFontEntry(pwcFileName,EXT_FOT))
        {
        // this is an .fot entry, must find ttf pointed to by .fot,
        // but first must get the full path to the .fot file
        // for cGetTTFFromFOT routine expects it. We will also need
        // the full path to the .fot file so that we can delete it
        // eventually.

            if (bMakePathNameW(awcTmpBuf, pwcFileName,NULL, &fl2))
            {
                if (cGetTTFFromFOT(awcTmpBuf, MAX_PATH, awcTTF, &fl, &flEmbed, &dwPidTid) &&
                    !(fl & FONT_ISNOT_FOT))
                {
                // fix the entry to point to .ttf file. At this point
                // awcTTF points to the FULL path to the .ttf file.
                // However, we will only need a relative path to the
                // .ttf file, when the .ttf file is in the %windir%\system
                // or %windir%\fonts directories. In case the file is in the
                // %windir%\system directory we shall copy it to %windir%\fonts
                // directory and write the relative path to the registry.
                // In case it is in the %windir%\fonts directory we do not
                // touch the file and also just write the relative path to the
                // registry. In any other case we just write the full .ttf
                // path to the registry.

                // first delete the .fot file, it is no longer needed

                    if (bFot && !gbWin31Upgrade)
                    {
                        UserVerify(DeleteFileW(awcTmpBuf));
                    }

                    if ((fl & (FONT_IN_FONTS_DIR | FONT_IN_SYSTEM_DIR)) == 0)
                    {
                    // if ttf file is not in either the system or the fonts
                    // directories, just write the full path to the registry

                        pwcTTF = awcTTF;
                    }
                    else
                    {
                    // find the bare file part, this is what will be written
                    // in the registry

                        pwcTTF = &awcTTF[wcslen(awcTTF) - 1];
                        while ((pwcTTF >= awcTTF) && (*pwcTTF != L'\\') && (*pwcTTF != L':'))
                            pwcTTF--;
                        pwcTTF++;

                        if (fl & FONT_IN_SYSTEM_DIR)
                        {
                        // need to move the ttf to fonts dir, can reuse the
                        // buffer on the stack:

                            wcscpy(awcTmpBuf, gpwcFontsDir);
                            lstrcatW(awcTmpBuf, L"\\");
                            lstrcatW(awcTmpBuf, pwcTTF);

                        // note that MoveFile should succeed, for if there was
                        // a ttf file of the same file name in %windir%\fonts dir
                        // we would not have been in this code path.

                                RIPMSG2(RIP_VERBOSE, "Moving %ws to %ws", awcTTF, awcTmpBuf);
                                if (!gbWin31Upgrade)
                                {
                                    UserVerify(MoveFileW(awcTTF, awcTmpBuf));
                                }
                                else
                                {
                                // Boolean value TRUE means "do not copy if target exists"

                                    UserVerify(CopyFileW(awcTTF, awcTmpBuf, TRUE));
                                }
                        }
                    }

                    RIPMSG2(RIP_VERBOSE, "writing to the registry:\n    %ws=%ws", pwcValueName, pwcTTF);
                    UserVerify(ERROR_SUCCESS ==
                            RegSetValueExW(
                                hkey,          // here is the key
                                pwcValueName,
                                0,
                                REG_SZ,
                                (CONST BYTE*) pwcTTF,
                                (DWORD)((wcslen(pwcTTF)+1) * sizeof(WCHAR))));
                }
                #ifdef DEBUG
                else
                {
                    RIPMSG1(RIP_WARNING, "Could not locate ttf pointed to by %ws", awcTmpBuf);
                }
                #endif
            }
            #ifdef DEBUG
            else
            {
                RIPMSG1(RIP_WARNING, "Could not locate .fot:  %ws", pwcFileName);
            }
            #endif
        }
    }
    else
    {
    // not a true type case. little bit simpler,
    // we will use awcTTF buffer for the full path name, and pwcTTF
    // as local variable even though these TTF names are misnomer
    // for these are not tt fonts

        if (bMakePathNameW(awcTTF, pwcFileName,NULL, &fl))
        {
        // At this point
        // awcTTF points to the FULL path to the font file.

        // If the font is in the system subdirectory we will just move it
        // to the fonts subdirectory. If the path in the registry is relative
        // we will leave it alone. If it is an absolute path, we shall
        // fix the registry entry to only contain relative path, the
        // absolute path is redundant.

            if (fl & (FONT_IN_SYSTEM_DIR | FONT_IN_FONTS_DIR))
            {
            // find the bare file part, this is what will be written
            // in the registry

                pwcTTF = &awcTTF[wcslen(awcTTF) - 1];
                while ((pwcTTF >= awcTTF) && (*pwcTTF != L'\\') && (*pwcTTF != L':'))
                    pwcTTF--;
                pwcTTF++;

                if (fl & FONT_IN_SYSTEM_DIR)
                {
                // need to move the font to fonts dir, can reuse the
                // buffer on the stack to build the full destination path

                    wcscpy(awcTmpBuf, gpwcFontsDir);
                    lstrcatW(awcTmpBuf, L"\\");
                    lstrcatW(awcTmpBuf, pwcTTF);

                // note that MoveFile should succeed, for if there was
                // a font file of the same file name in %windir%\fonts dir
                // we would not have been in this code path. The only time
                // it could fail if the path in the registry is absolute.

                    RIPMSG2(RIP_VERBOSE, "Moving %ws to %ws", awcTTF, awcTmpBuf);
                    if (!gbWin31Upgrade)
                    {
                        UserVerify(MoveFileW(awcTTF, awcTmpBuf));
                    }
                    else
                    {
                    // Boolean value TRUE means "do not copy if target exists"

                        UserVerify(CopyFileW(awcTTF, awcTmpBuf, TRUE));
                    }
                }

            // check if the file path in the registry is absolute,
            // if so make it relative:

                if (!(fl & FONT_RELATIVE_PATH))
                {
                    RIPMSG2(RIP_VERBOSE, "writing to the registry:\n    %ws=%ws", pwcValueName, pwcTTF);
                    UserVerify(ERROR_SUCCESS ==
                            RegSetValueExW(
                                    hkey,          // here is the key
                                    pwcValueName,
                                    0,
                                    REG_SZ,
                                    (CONST BYTE*) pwcTTF,
                                    (DWORD)((wcslen(pwcTTF)+1) * sizeof(WCHAR))));
                }
            }
        }
    }
}
コード例 #21
0
ファイル: winable2.c プロジェクト: conioh/os-design
/*****************************************************************************\
*
*  GetGUIThreadInfo()
*
*  This gets GUI information out of context.  If you pass in a NULL thread ID,
*  we will get the 'global' information, using the foreground thread.  This
*  is guaranteed to be the real active window, focus window, etc.  Yes, you
*  could do it yourself by calling GetForegroundWindow, getting the thread ID
*  of that window via GetWindowThreadProcessId, then passing the ID into
*  GetGUIThreadInfo().  However, that takes three calls and aside from being
*  a pain, anything could happen in the middle.  So passing in NULL gets
*  you stuff in one call and hence also works right.
*
*  This function returns FALSE if the thread doesn't have a queue or the
*  thread ID is bogus.
*
\*****************************************************************************/
BOOL WINAPI
_GetGUIThreadInfo(PTHREADINFO pti, PGUITHREADINFO pgui)
{
    PQ pq;

    /*
     * Validate threadinfo structure
     */
    if (pgui->cbSize != sizeof(GUITHREADINFO)) {
        RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "GUITHREADINFO.cbSize %d is wrong", pgui->cbSize);
        return FALSE;
    }

    /*
     * Is this a valid initialized GUI thread?
     */
    if (pti != NULL) {
        if ((pq = pti->pq) == NULL) {
            // does this ever happen?
            RIPMSG1(RIP_ERROR, "GetGUIThreadInfo: No queue for pti %lx", pti);
            return FALSE;
        }
    } else {
        /*
         * Use the foreground queue. To get menu state information we must also
         * figure out the right pti.  This matches _GetForegroundWindow() logic.
         */
        if ((pq = gpqForeground) == NULL) {
            // this does sometimes happen...
            RIPMSG0(RIP_WARNING, "GetGUIThreadInfo: No foreground queue");
            return FALSE;
        }

        if (pq->spwndActive && (GETPTI(pq->spwndActive)->pq == pq)) {
            pti = GETPTI(pq->spwndActive);
            if (PtiCurrentShared()->rpdesk != pti->rpdesk) {
                RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Foreground window on different desktop");
                return FALSE;
            }
        }
    }

    UserAssert(pq != NULL);

    /*
     * For C2 security, verify that pq and pti are on the current thread's desktop.
     * We can't directly determine which desktop pq belongs to, but we can at
     * least ensure that any caret info we return is not from another desktop
     */
    if (pq->caret.spwnd &&
            (GETPTI(pq->caret.spwnd)->rpdesk != PtiCurrentShared()->rpdesk)) {
        RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Foreground caret on different desktop");
        return FALSE;
    }
    if (pti && (pti->rpdesk != PtiCurrentShared()->rpdesk)) {
        RIPERR0(ERROR_ACCESS_DENIED, RIP_VERBOSE, "Foreground thread on different desktop");
        return FALSE;
    }

    pgui->flags        = 0;
    pgui->hwndMoveSize = NULL;
    pgui->hwndMenuOwner = NULL;

    /*
     * Get Menu information from the THREADINFO
     */
    if (pti != NULL) {
        if (pti->pmsd && !pti->pmsd->fTrackCancelled && pti->pmsd->spwnd) {
            pgui->flags |= GUI_INMOVESIZE;
            pgui->hwndMoveSize = HWq(pti->pmsd->spwnd);
        }

        if (pti->pMenuState && pti->pMenuState->pGlobalPopupMenu) {
            pgui->flags |= GUI_INMENUMODE;

            if (pti->pMenuState->pGlobalPopupMenu->fHasMenuBar) {
                if (pti->pMenuState->pGlobalPopupMenu->fIsSysMenu) {
                    pgui->flags |= GUI_SYSTEMMENUMODE;
                }
            } else {
                pgui->flags |= GUI_POPUPMENUMODE;
            }

            if (pti->pMenuState->pGlobalPopupMenu->spwndNotify)
                pgui->hwndMenuOwner = HWq(pti->pMenuState->pGlobalPopupMenu->spwndNotify);
        }
    }

    /*
     * Get the rest of the information from the queue
     */
    pgui->hwndActive   = HW(pq->spwndActive);
    pgui->hwndFocus    = HW(pq->spwndFocus);
    pgui->hwndCapture  = HW(pq->spwndCapture);

    pgui->hwndCaret    = NULL;

    if (pq->caret.spwnd) {
        pgui->hwndCaret = HWq(pq->caret.spwnd);

        /*
         * These coords are always relative to the client of hwndCaret
         * of course.
         */
        pgui->rcCaret.left   = pq->caret.x;
        pgui->rcCaret.right  = pgui->rcCaret.left + pq->caret.cx;
        pgui->rcCaret.top    = pq->caret.y;
        pgui->rcCaret.bottom = pgui->rcCaret.top + pq->caret.cy;

        if (pq->caret.iHideLevel == 0)
            pgui->flags |= GUI_CARETBLINKING;
    } else if (pti && (pti->ppi->W32PF_Flags & W32PF_CONSOLEHASFOCUS)) {
        /*
         * The thread is running in the console window with focus. Pull
         * out the info from the console pseudo caret.
         */
        pgui->hwndCaret = pti->rpdesk->cciConsole.hwnd;
        pgui->rcCaret = pti->rpdesk->cciConsole.rc;
    } else {
        SetRectEmpty(&pgui->rcCaret);
    }

    return TRUE;
}
コード例 #22
0
ファイル: mnapi.c プロジェクト: conioh/os-design
void xxxEndMenu(
    PMENUSTATE pMenuState)
{
    BOOL fMenuStateOwner;
    PPOPUPMENU  ppopup;
    PTHREADINFO ptiCurrent;

    if ((ppopup = pMenuState->pGlobalPopupMenu) == NULL) {

        /*
         * We're not really in menu mode. This can happen
         *  if we are forced out of menu loop too soon; i.e, from
         *  inside xxxMNGetPopup or xxxTrackPopupMenuEx.
         */
         UserAssert(!pMenuState->fInsideMenuLoop && !pMenuState->fMenuStarted);
        return;
    }



    pMenuState->fInsideMenuLoop = FALSE;
    pMenuState->fMenuStarted = FALSE;
    /*
     * Mark the popup as destroyed so people will not use it anymore.
     * This means that root popups can be marked as destroyed before
     * actually being destroyed (nice and confusing).
     */
    ppopup->fDestroyed = TRUE;

    /*
     * Determine if this is the menu loop owner before calling back.
     * Only the owner can destroy the menu windows
     */
   ptiCurrent = PtiCurrent();
   fMenuStateOwner = (ptiCurrent == pMenuState->ptiMenuStateOwner);

    /*
     * Release mouse capture if we got it in xxxStartMenuState
     */
    if (ptiCurrent->pq->spwndCapture == pMenuState->pGlobalPopupMenu->spwndNotify) {
        xxxMNReleaseCapture();
    }

    /*
     * Bail if this is not the menu loop owner
     */
    if (!fMenuStateOwner) {
        RIPMSG1(RIP_WARNING, "xxxEndMenu: Thread %#p doesn't own the menu loop", ptiCurrent);
        return;
    }
    /*
     * If the menu loop is running on a thread different than the thread
     *  that owns spwndNotify, we can have two threads trying to end
     *  this menu at the same time.
     */
    if (pMenuState->fInEndMenu) {
        RIPMSG1(RIP_WARNING, "xxxEndMenu: already in EndMenu. pMenuState:%#p", pMenuState);
        return;
    }
    pMenuState->fInEndMenu = TRUE;

    if (pMenuState->pGlobalPopupMenu->spwndNotify != NULL) {
        if (!pMenuState->pGlobalPopupMenu->fInCancel) {
            xxxMNDismiss(pMenuState);
        }
    } else {
        BOOL    fTrackedPopup = ppopup->fIsTrackPopup;

        /*
         * This should do the same stuff as MenuCancelMenus but not send any
         * messages...
         */
        xxxMNCloseHierarchy(ppopup, pMenuState);

        if (fTrackedPopup) {
            xxxDestroyWindow(ppopup->spwndPopupMenu);
        }

    }

}
コード例 #23
0
ファイル: lb1.c プロジェクト: conioh/os-design
LRESULT APIENTRY ListBoxWndProcWorker(
    PWND pwnd,
    UINT message,
    WPARAM wParam,
    LPARAM lParam,
    DWORD fAnsi)
{
    HWND hwnd = HWq(pwnd);
    PAINTSTRUCT ps;
    HDC         hdc;
    LPRECT      lprc;
    PLBIV plb;    /* List Box Instance Variable */
    INT iSel;     /* Index of selected item */
    DWORD dw;
    TL tlpwndParent;
    UINT wFlags;
    LPWSTR lpwsz = NULL;
    LRESULT lReturn = 0;
    static BOOL fInit = TRUE;

    CheckLock(pwnd);

    VALIDATECLASSANDSIZE(pwnd, FNID_LISTBOX);
    INITCONTROLLOOKASIDE(&ListboxLookaside, LBIV, spwnd, 4);

    /*
     * Get the plb for the given window now since we will use it a lot in
     * various handlers. This was stored using SetWindowLong(hwnd,0,plb)
     * when the listbox was first created (by INITCONTROLLOOKASIDE above)
     */
    plb = ((PLBWND)pwnd)->pLBIV;

    /*
     * Handle ANSI translations of input parameters
     */
    if (fAnsi) {
        switch (message) {
        case LB_ADDSTRING:
        case LB_ADDSTRINGUPPER:
        case LB_ADDSTRINGLOWER:
        case LB_FINDSTRING:
        case LB_FINDSTRINGEXACT:
        case LB_INSERTSTRING:
        case LB_INSERTSTRINGUPPER:
        case LB_INSERTSTRINGLOWER:
        case LB_SELECTSTRING:
            if (!plb->fHasStrings) {
                break;
            }
            // Fall through...
        case LB_ADDFILE:
        case LB_DIR:
            if (lParam) {
                if (!MBToWCS((LPSTR)lParam, -1, &lpwsz, -1, TRUE))
                    return LB_ERR;
            }
            break;
        default:
            break;
        }
        if (lpwsz) {
            lParam = (LPARAM)lpwsz;
        }
    }

    switch (message) {

    case LB_GETTOPINDEX:        // Return index of top item displayed.
        return plb->iTop;

    case LB_SETTOPINDEX:
        if (wParam && ((INT)wParam < 0 || (INT)wParam >= plb->cMac)) {
            RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, "");
            return LB_ERR;
        }
        if (plb->cMac) {
            xxxNewITop(plb, (INT)wParam);
        }
        break;

    case WM_STYLECHANGED:
        plb->fRtoLReading = (TestWF(pwnd, WEFRTLREADING) != 0);
        plb->fRightAlign  = (TestWF(pwnd, WEFRIGHT) != 0);
        xxxCheckRedraw(plb, FALSE, 0);
        break;

    case WM_WINDOWPOSCHANGED:

        /*
         * If we are in the middle of creation, ignore this
         * message because it will generate a WM_SIZE message.
         * See xxxLBCreate().
         */
        if (!plb->fIgnoreSizeMsg)
            goto CallDWP;
        break;

    case WM_SIZE:

        /*
         * If we are in the middle of creation, ignore size
         * messages.  See xxxLBCreate().
         */
        if (!plb->fIgnoreSizeMsg)
            xxxLBSize(plb, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        break;

    case WM_ERASEBKGND:
        ThreadLock(plb->spwndParent, &tlpwndParent);
        FillWindow(HW(plb->spwndParent), hwnd, (HDC)wParam,
                (HBRUSH)CTLCOLOR_LISTBOX);
        ThreadUnlock(&tlpwndParent);
        return TRUE;

    case LB_RESETCONTENT:
        xxxLBResetContent(plb);
        break;

    case WM_TIMER:
        if (wParam == IDSYS_LBSEARCH) {
            plb->iTypeSearch = 0;
            NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
            xxxInvertLBItem(plb, plb->iSel, TRUE);
            break;
        }

        message = WM_MOUSEMOVE;
        xxxTrackMouse(plb, message, plb->ptPrev);
        break;

        /*
         * Fall through
         */
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_LBUTTONDBLCLK:
        {
            POINT pt;

            POINTSTOPOINT(pt, lParam);
            xxxTrackMouse(plb, message, pt);
        }
        break;

    case WM_MBUTTONDOWN:
        EnterReaderModeHelper(hwnd);
        break;

    case WM_CAPTURECHANGED:
            //
            // Note that this message should be handled only on unexpected
            // capture changes currently.
            //
        UserAssert(TestWF(pwnd, WFWIN40COMPAT));
        if (plb->fCaptured)
            xxxLBButtonUp(plb, LBUP_NOTIFY);
        break;

    case LBCB_STARTTRACK:
        //
        // Start tracking mouse moves in the listbox, setting capture
        //
        if (!plb->pcbox)
            break;

        plb->fCaptured = FALSE;
        if (wParam) {
            POINT pt;

            POINTSTOPOINT(pt, lParam);

            _ScreenToClient(pwnd, &pt);
            xxxTrackMouse(plb, WM_LBUTTONDOWN, pt);
        } else {
            NtUserSetCapture(hwnd);
            plb->fCaptured = TRUE;
            plb->iLastSelection = plb->iSel;
        }
        break;

    case LBCB_ENDTRACK:
        // Kill capture, tracking, etc.
        if (plb->fCaptured)
            xxxLBButtonUp(plb, LBUP_RELEASECAPTURE | (wParam ? LBUP_SELCHANGE :
                LBUP_RESETSELECTION));
        break;

    case WM_PRINTCLIENT:
        xxxLBPaint(plb, (HDC) wParam, NULL);
        break;

    case WM_PAINT:
        if (wParam) {
            hdc = (HDC) wParam;
            lprc = NULL;
        } else {
            hdc = NtUserBeginPaint(hwnd, &ps);
            lprc = &(ps.rcPaint);
        }

        if (IsLBoxVisible(plb))
            xxxLBPaint(plb, hdc, lprc);

        if (!wParam)
            NtUserEndPaint(hwnd, &ps);
        break;

    case WM_NCDESTROY:
    case WM_FINALDESTROY:
        xxxDestroyLBox(plb, pwnd);
        break;

    case WM_SETFOCUS:
// DISABLED in Win 3.1        xxxUpdateWindow(pwnd);
        CaretCreate(plb);
        xxxLBSetCaret(plb, TRUE);
        xxxNotifyOwner(plb, LBN_SETFOCUS);
        if (FWINABLE()) {
            if (_IsWindowVisible(pwnd)) {
                LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase);
            }
        }
        break;

    case WM_KILLFOCUS:
        /*
         * Reset the wheel delta count.
         */
        gcWheelDelta = 0;

        xxxLBSetCaret(plb, FALSE);
        xxxCaretDestroy(plb);
        xxxNotifyOwner(plb, LBN_KILLFOCUS);
        if (plb->iTypeSearch) {
            plb->iTypeSearch = 0;
            NtUserKillTimer(hwnd, IDSYS_LBSEARCH);
        }
        if (plb->pszTypeSearch) {
            UserLocalFree(plb->pszTypeSearch);
            plb->pszTypeSearch = NULL;
        }
        break;

    case WM_MOUSEWHEEL:
        {
            int     cDetants;
            int     cPage;
            int     cLines;
            RECT    rc;
            int     windowWidth;
            int     cPos;

            /*
             * Don't handle zoom and datazoom.
             */
            if (wParam & (MK_SHIFT | MK_CONTROL)) {
                goto CallDWP;
            }

            lReturn = 1;
            gcWheelDelta -= (short) HIWORD(wParam);
            cDetants = gcWheelDelta / WHEEL_DELTA;
            if (    cDetants != 0 &&
                    gpsi->ucWheelScrollLines > 0 &&
                    (pwnd->style & (WS_VSCROLL | WS_HSCROLL))) {

                gcWheelDelta = gcWheelDelta % WHEEL_DELTA;

                if (pwnd->style & WS_VSCROLL) {
                    cPage = max(1, (plb->cItemFullMax - 1));
                    cLines = cDetants *
                            (int) min((UINT) cPage, gpsi->ucWheelScrollLines);

                    cPos = max(0, min(plb->iTop + cLines, plb->cMac - 1));
                    if (cPos != plb->iTop) {
                        xxxLBoxCtlScroll(plb, SB_THUMBPOSITION, cPos);
                        xxxLBoxCtlScroll(plb, SB_ENDSCROLL, 0);
                    }
                } else if (plb->fMultiColumn) {
                    cPage = max(1, plb->numberOfColumns);
                    cLines = cDetants * (int) min((UINT) cPage, gpsi->ucWheelScrollLines);
                    cPos = max(
                            0,
                            min((plb->iTop / plb->itemsPerColumn) + cLines,
                                plb->cMac - 1 - ((plb->cMac - 1) % plb->itemsPerColumn)));

                    if (cPos != plb->iTop) {
                        xxxLBoxCtlHScrollMultiColumn(plb, SB_THUMBPOSITION, cPos);
                        xxxLBoxCtlHScrollMultiColumn(plb, SB_ENDSCROLL, 0);
                    }
                } else {
                    _GetClientRect(plb->spwnd, &rc);
                    windowWidth = rc.right;
                    cPage = max(plb->cxChar, (windowWidth / 3) * 2) /
                            plb->cxChar;

                    cLines = cDetants *
                            (int) min((UINT) cPage, gpsi->ucWheelScrollLines);

                    cPos = max(
                            0,
                            min(plb->xOrigin + (cLines * plb->cxChar),
                                plb->maxWidth));

                    if (cPos != plb->xOrigin) {
                        xxxLBoxCtlHScroll(plb, SB_THUMBPOSITION, cPos);
                        xxxLBoxCtlHScroll(plb, SB_ENDSCROLL, 0);
                    }
                }
            }
        }
        break;

    case WM_VSCROLL:
        xxxLBoxCtlScroll(plb, LOWORD(wParam), HIWORD(wParam));
        break;

    case WM_HSCROLL:
        xxxLBoxCtlHScroll(plb, LOWORD(wParam), HIWORD(wParam));
        break;

    case WM_GETDLGCODE:
        return DLGC_WANTARROWS | DLGC_WANTCHARS;

    case WM_CREATE:
        return xxxLBCreate(plb, pwnd, (LPCREATESTRUCT) lParam);

    case WM_SETREDRAW:

        /*
         * If wParam is nonzero, the redraw flag is set
         * If wParam is zero, the flag is cleared
         */
        xxxLBSetRedraw(plb, (wParam != 0));
        break;

    case WM_ENABLE:
        xxxLBInvalidateRect(plb, NULL, !plb->OwnerDraw);
        break;

    case WM_SETFONT:
        xxxLBSetFont(plb, (HANDLE)wParam, LOWORD(lParam));
        break;

    case WM_GETFONT:
        return (LRESULT)plb->hFont;

    case WM_DRAGSELECT:
    case WM_DRAGLOOP:
    case WM_DRAGMOVE:
    case WM_DROPFILES:
        ThreadLock(plb->spwndParent, &tlpwndParent);
        lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam);
        ThreadUnlock(&tlpwndParent);
        return lReturn;


    case WM_QUERYDROPOBJECT:
    case WM_DROPOBJECT:

        /*
         * fix up control data, then pass message to parent
         */
        LBDropObjectHandler(plb, (PDROPSTRUCT)lParam);
        ThreadLock(plb->spwndParent, &tlpwndParent);
        lReturn = SendMessage(HW(plb->spwndParent), message, wParam, lParam);
        ThreadUnlock(&tlpwndParent);
        return lReturn;

    case LB_GETITEMRECT:
        return LBGetItemRect(plb, (INT)wParam, (LPRECT)lParam);

    case LB_GETITEMDATA:
        return LBGetItemData(plb, (INT)wParam);  // wParam = item index

    case LB_SETITEMDATA:

        /*
         * wParam is item index
         */
        return LBSetItemData(plb, (INT)wParam, lParam);

    case LB_ADDSTRINGUPPER:
        wFlags = UPPERCASE | LBI_ADD;
        goto CallInsertItem;

    case LB_ADDSTRINGLOWER:
        wFlags = LOWERCASE | LBI_ADD;
        goto CallInsertItem;

    case LB_ADDSTRING:
        wFlags = LBI_ADD;
        goto CallInsertItem;

    case LB_INSERTSTRINGUPPER:
        wFlags = UPPERCASE;
        goto CallInsertItem;

    case LB_INSERTSTRINGLOWER:
        wFlags = LOWERCASE;
        goto CallInsertItem;

    case LB_INSERTSTRING:
        wFlags = 0;
CallInsertItem:
        lReturn = ((LRESULT) xxxLBInsertItem(plb, (LPWSTR) lParam, (int) wParam, wFlags));
        break;

    case LB_INITSTORAGE:
        return xxxLBInitStorage(plb, fAnsi, (INT)wParam, (INT)lParam);

    case LB_DELETESTRING:
        return xxxLBoxCtlDelete(plb, (INT)wParam);

    case LB_DIR:
        /*
         * wParam - Dos attribute value.
         * lParam - Points to a file specification string
         */
        lReturn = xxxLbDir(plb, (INT)wParam, (LPWSTR)lParam);
        break;

    case LB_ADDFILE:
        lReturn = xxxLbInsertFile(plb, (LPWSTR)lParam);
        break;

    case LB_SETSEL:
        return xxxLBSetSel(plb, (wParam != 0), (INT)lParam);

    case LB_SETCURSEL:
        /*
         * If window obscured, update so invert will work correctly
         */
// DISABLED in Win 3.1        xxxUpdateWindow(pwnd);
        return xxxLBSetCurSel(plb, (INT)wParam);

    case LB_GETSEL:
        if (wParam >= (UINT) plb->cMac)
                return((LRESULT) LB_ERR);

        return IsSelected(plb, (INT)wParam, SELONLY);

    case LB_GETCURSEL:
        if (plb->wMultiple == SINGLESEL) {
            return plb->iSel;
        }
        return plb->iSelBase;

    case LB_SELITEMRANGE:
        if (plb->wMultiple == SINGLESEL) {
            /*
             * Can't select a range if only single selections are enabled
             */
            RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SELITEMRANGE");
            return LB_ERR;
        }

        xxxLBSelRange(plb, LOWORD(lParam), HIWORD(lParam), (wParam != 0));
        break;

    case LB_SELITEMRANGEEX:
        if (plb->wMultiple == SINGLESEL) {
            /*
             * Can't select a range if only single selections are enabled
             */
            RIPERR0(ERROR_INVALID_LB_MESSAGE, RIP_VERBOSE,"LB_SELITEMRANGEEX:Can't select a range if only single selections are enabled");
            return LB_ERR;
        } else {
            BOOL fHighlight = ((DWORD)lParam > (DWORD)wParam);
            if (fHighlight == FALSE) {
                ULONG_PTR temp = lParam;
                lParam = wParam;
                wParam = temp;
            }
            xxxLBSelRange(plb, (INT)wParam, (INT)lParam, fHighlight);
        }
        break;

    case LB_GETTEXTLEN:
        if (lParam != 0) {
            RIPMSG1(RIP_WARNING, "LB_GETTEXTLEN with lParam = %lx\n", lParam);
        }
        lReturn = LBGetText(plb, TRUE, fAnsi, (INT)wParam, NULL);
        break;

    case LB_GETTEXT:
        lReturn = LBGetText(plb, FALSE, fAnsi, (INT)wParam, (LPWSTR)lParam);
        break;

    case LB_GETCOUNT:
        // Lotus Approach calls CallWndProc(ListWndProc, LB_GETCOUNT,...)
        // on a window that doesn't have a plb yet. So, we need to make
        // this check. Bug #6675 - 11/7/94 --
        if(plb)
            return((LRESULT) plb->cMac);
        else
            return(0);

    case LB_SETCOUNT:
        return xxxLBSetCount(plb, (INT)wParam);

    case LB_SELECTSTRING:
    case LB_FINDSTRING:
        iSel = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, PREFIX, TRUE);
        if (message == LB_FINDSTRING || iSel == LB_ERR) {
            lReturn = iSel;
        } else {
            lReturn = xxxLBSetCurSel(plb, iSel);
        }
        break;

    case LB_GETLOCALE:
        return plb->dwLocaleId;

    case LB_SETLOCALE:

        /*
         * Validate locale
         */
        wParam = ConvertDefaultLocale((LCID)wParam);
        if (!IsValidLocale((LCID)wParam, LCID_INSTALLED))
            return LB_ERR;

        dw = plb->dwLocaleId;
        plb->dwLocaleId = (DWORD)wParam;
        return dw;

    case WM_KEYDOWN:

        /*
         * IanJa: Use LOWORD() to get low 16-bits of wParam - this should
         * work for Win16 & Win32.  The value obtained is the virtual key
         */
        xxxLBoxCtlKeyInput(plb, message, LOWORD(wParam));
        break;

    case WM_CHAR:
        xxxLBoxCtlCharInput(plb, LOWORD(wParam), fAnsi);
        break;

    case LB_GETSELITEMS:
    case LB_GETSELCOUNT:

        /*
         * IanJa/Win32 should this be LPWORD now?
         */
        return LBoxGetSelItems(plb, (message == LB_GETSELCOUNT), (INT)wParam,
                (LPINT)lParam);

    case LB_SETTABSTOPS:

        /*
         * IanJa/Win32: Tabs given by array of INT for backwards compatability
         */
        return LBSetTabStops(plb, (INT)wParam, (LPINT)lParam);

    case LB_GETHORIZONTALEXTENT:

        /*
         * Return the max width of the listbox used for horizontal scrolling
         */
        return plb->maxWidth;

    case LB_SETHORIZONTALEXTENT:

        /*
         * Set the max width of the listbox used for horizontal scrolling
         */
        if (plb->maxWidth != (INT)wParam) {
            plb->maxWidth = (INT)wParam;

            /*
             * When horizontal extent is set, Show/hide the scroll bars.
             * NOTE: LBShowHideScrollBars() takes care if Redraw is OFF.
             * Fix for Bug #2477 -- 01/14/91 -- SANKAR --
             */
            xxxLBShowHideScrollBars(plb); //Try to show or hide scroll bars
            if (plb->fHorzBar && plb->fRightAlign && !(plb->fMultiColumn || plb->OwnerDraw)) {
                /*
                 * origin to right
                 */
                xxxLBoxCtlHScroll(plb, SB_BOTTOM, 0);
            }
        }
        break;    /* originally returned register ax (message) ! */

    case LB_SETCOLUMNWIDTH:

        /*
         * Set the width of a column in a multicolumn listbox
         */
        plb->cxColumn = (INT)wParam;
        LBCalcItemRowsAndColumns(plb);
        if (IsLBoxVisible(plb))
            NtUserInvalidateRect(hwnd, NULL, TRUE);
        xxxLBShowHideScrollBars(plb);
        break;

    case LB_SETANCHORINDEX:
        if ((INT)wParam >= plb->cMac) {
            RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETANCHORINDEX");
            return LB_ERR;
        }
        plb->iMouseDown = (INT)wParam;
        plb->iLastMouseMove = (INT)wParam;
        xxxInsureVisible(plb, (int) wParam, (BOOL)(lParam != 0));
        break;

    case LB_GETANCHORINDEX:
        return plb->iMouseDown;

    case LB_SETCARETINDEX:
        if ( (plb->iSel == -1) || ((plb->wMultiple != SINGLESEL) &&
                    (plb->cMac > (INT)wParam))) {

            /*
             * Set's the iSelBase to the wParam
             * if lParam, then don't scroll if partially visible
             * else scroll into view if not fully visible
             */
            xxxInsureVisible(plb, (INT)wParam, (BOOL)LOWORD(lParam));
            xxxSetISelBase(plb, (INT)wParam);
            break;
        } else {
            if ((INT)wParam >= plb->cMac) {
                RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE,"Invalid index passed to LB_SETCARETINDEX");
            }
            return LB_ERR;
        }
        break;

    case LB_GETCARETINDEX:
        return plb->iSelBase;

    case LB_SETITEMHEIGHT:
    case LB_GETITEMHEIGHT:
        return LBGetSetItemHeightHandler(plb, message, (INT)wParam, LOWORD(lParam));
        break;

    case LB_FINDSTRINGEXACT:
        lReturn = xxxFindString(plb, (LPWSTR)lParam, (INT)wParam, EQ, TRUE);
        break;

    case LB_ITEMFROMPOINT: {
        POINT pt;
        BOOL bOutside;
        DWORD dwItem;

        POINTSTOPOINT(pt, lParam);
        bOutside = ISelFromPt(plb, pt, &dwItem);
        UserAssert(bOutside == 1 || bOutside == 0);
        return (LRESULT)MAKELONG(dwItem, bOutside);
    }

    case LBCB_CARETON:

        /*
         * Internal message for combo box support
         */
        CaretCreate(plb);
        // Set up the caret in the proper location for drop downs.
        plb->iSelBase = plb->iSel;
        xxxLBSetCaret(plb, TRUE);
        if (FWINABLE()) {
            if (_IsWindowVisible(pwnd)) {
                LBEvent(plb, EVENT_OBJECT_FOCUS, plb->iSelBase);
            }
        }
        return(plb->iSel);

    case LBCB_CARETOFF:

        /*
         * Internal message for combo box support
         */
        xxxLBSetCaret(plb, FALSE);
        xxxCaretDestroy(plb);
        break;

    case WM_NCCREATE:
        if ((pwnd->style & LBS_MULTICOLUMN) && (pwnd->style & WS_VSCROLL))
        {
            DWORD mask = WS_VSCROLL;
            DWORD flags = 0;
            if (!TestWF(pwnd, WFWIN40COMPAT)) {
                mask |= WS_HSCROLL;
                flags = WS_HSCROLL;
            }
            NtUserAlterWindowStyle(hwnd, mask, flags);
        }
        goto CallDWP;

     default:
CallDWP:
        return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
    }

    /*
     * Handle translation of ANSI output data and free buffer
     */
    if (lpwsz) {
        UserLocalFree(lpwsz);
    }

    return lReturn;
}