fixed line endings on all files
authorVizzini <vizzini@plasmic.com>
Mon, 6 Oct 2003 16:13:28 +0000 (16:13 +0000)
committerVizzini <vizzini@plasmic.com>
Mon, 6 Oct 2003 16:13:28 +0000 (16:13 +0000)
svn path=/trunk/; revision=6249

31 files changed:
reactos/lib/comctl32/animate.c
reactos/lib/comctl32/comboex.c
reactos/lib/comctl32/comctl32.def
reactos/lib/comctl32/comctl32.edf
reactos/lib/comctl32/comctl32.h
reactos/lib/comctl32/comctl32.rc
reactos/lib/comctl32/comctl32undoc.c
reactos/lib/comctl32/commctrl.c
reactos/lib/comctl32/datetime.c
reactos/lib/comctl32/draglist.c
reactos/lib/comctl32/flatsb.c
reactos/lib/comctl32/header.c
reactos/lib/comctl32/hotkey.c
reactos/lib/comctl32/imagelist.c
reactos/lib/comctl32/imagelist.h
reactos/lib/comctl32/ipaddress.c
reactos/lib/comctl32/listview.c
reactos/lib/comctl32/monthcal.c
reactos/lib/comctl32/nativefont.c
reactos/lib/comctl32/pager.c
reactos/lib/comctl32/progress.c
reactos/lib/comctl32/propsheet.c
reactos/lib/comctl32/rebar.c
reactos/lib/comctl32/smoothscroll.c
reactos/lib/comctl32/status.c
reactos/lib/comctl32/tab.c
reactos/lib/comctl32/toolbar.c
reactos/lib/comctl32/tooltips.c
reactos/lib/comctl32/trackbar.c
reactos/lib/comctl32/treeview.c
reactos/lib/comctl32/updown.c

index d12ec04..4c7a3cb 100644 (file)
-/* -*- tab-width: 8; c-basic-offset: 4 -*- */\r
-/*\r
- * Animation control\r
- *\r
- * Copyright 1998, 1999 Eric Kohl\r
- *                1999 Eric Pouech\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * NOTES\r
- *   I will only improve this control once in a while.\r
- *     Eric <ekohl@abo.rhein-zeitung.de>\r
- *\r
- * TODO:\r
- *   - check for the 'rec ' list in some AVI files\r
- *   - concurrent access to infoPtr\r
- */\r
-\r
-#define COM_NO_WINDOWS_H\r
-#include <stdarg.h>\r
-#include <string.h>\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "wingdi.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-#include "commctrl.h"\r
-#include "vfw.h"\r
-#include "mmsystem.h"\r
-#include "comctl32.h"\r
-#include "wine/debug.h"\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(animate);\r
-\r
-static struct {\r
-    HMODULE    hModule;\r
-    HIC         (WINAPI *fnICOpen)(DWORD, DWORD, UINT);\r
-    LRESULT     (WINAPI *fnICClose)(HIC);\r
-    LRESULT     (WINAPI *fnICSendMessage)(HIC, UINT, DWORD, DWORD);\r
-    DWORD       (WINAPIV *fnICDecompress)(HIC,DWORD,LPBITMAPINFOHEADER,LPVOID,LPBITMAPINFOHEADER,LPVOID);\r
-} fnIC;\r
-\r
-typedef struct\r
-{\r
-   /* reference to input stream (file or resource) */\r
-   HGLOBAL             hRes;\r
-   HMMIO               hMMio;  /* handle to mmio stream */\r
-   HWND                        hWnd;\r
-   /* information on the loaded AVI file */\r
-   MainAVIHeader       mah;\r
-   AVIStreamHeader     ash;\r
-   LPBITMAPINFOHEADER  inbih;\r
-   LPDWORD             lpIndex;\r
-   /* data for the decompressor */\r
-   HIC                 hic;\r
-   LPBITMAPINFOHEADER  outbih;\r
-   LPVOID              indata;\r
-   LPVOID              outdata;\r
-   /* data for the background mechanism */\r
-   CRITICAL_SECTION    cs;\r
-   HANDLE              hThread;\r
-   UINT                        uTimer;\r
-   /* data for playing the file */\r
-   int                 nFromFrame;\r
-   int                 nToFrame;\r
-   int                 nLoop;\r
-   int                 currFrame;\r
-   /* tranparency info*/\r
-   COLORREF            transparentColor;\r
-   HBRUSH              hbrushBG;\r
-   HBITMAP             hbmPrevFrame;\r
-} ANIMATE_INFO;\r
-\r
-#define ANIMATE_GetInfoPtr(hWnd) ((ANIMATE_INFO *)GetWindowLongA(hWnd, 0))\r
-#define ANIMATE_COLOR_NONE     0xffffffff\r
-\r
-static void ANIMATE_Notify(ANIMATE_INFO* infoPtr, UINT notif)\r
-{\r
-    SendMessageA(GetParent(infoPtr->hWnd), WM_COMMAND,\r
-                MAKEWPARAM(GetDlgCtrlID(infoPtr->hWnd), notif),\r
-                (LPARAM)infoPtr->hWnd);\r
-}\r
-\r
-static BOOL ANIMATE_LoadResA(ANIMATE_INFO *infoPtr, HINSTANCE hInst, LPSTR lpName)\r
-{\r
-    HRSRC      hrsrc;\r
-    MMIOINFO   mminfo;\r
-    LPVOID     lpAvi;\r
-\r
-    hrsrc = FindResourceA(hInst, lpName, "AVI");\r
-    if (!hrsrc)\r
-       return FALSE;\r
-\r
-    infoPtr->hRes = LoadResource(hInst, hrsrc);\r
-    if (!infoPtr->hRes)\r
-       return FALSE;\r
-\r
-    lpAvi = LockResource(infoPtr->hRes);\r
-    if (!lpAvi)\r
-       return FALSE;\r
-\r
-    memset(&mminfo, 0, sizeof(mminfo));\r
-    mminfo.fccIOProc = FOURCC_MEM;\r
-    mminfo.pchBuffer = (LPSTR)lpAvi;\r
-    mminfo.cchBuffer = SizeofResource(hInst, hrsrc);\r
-    infoPtr->hMMio = mmioOpenA(NULL, &mminfo, MMIO_READ);\r
-    if (!infoPtr->hMMio) {\r
-       GlobalFree((HGLOBAL)lpAvi);\r
-       return FALSE;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static BOOL ANIMATE_LoadFileA(ANIMATE_INFO *infoPtr, LPSTR lpName)\r
-{\r
-    infoPtr->hMMio = mmioOpenA((LPSTR)lpName, NULL,\r
-                              MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);\r
-\r
-    if (!infoPtr->hMMio)\r
-       return FALSE;\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr)\r
-{\r
-    EnterCriticalSection(&infoPtr->cs);\r
-\r
-    /* should stop playing */\r
-    if (infoPtr->hThread)\r
-    {\r
-        if (!TerminateThread(infoPtr->hThread,0))\r
-            WARN("could not destroy animation thread!\n");\r
-           infoPtr->hThread = 0;\r
-    }\r
-    if (infoPtr->uTimer) {\r
-       KillTimer(infoPtr->hWnd, infoPtr->uTimer);\r
-       infoPtr->uTimer = 0;\r
-    }\r
-\r
-    LeaveCriticalSection(&infoPtr->cs);\r
-\r
-    ANIMATE_Notify(infoPtr, ACN_STOP);\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static void ANIMATE_Free(ANIMATE_INFO *infoPtr)\r
-{\r
-    if (infoPtr->hMMio) {\r
-       ANIMATE_DoStop(infoPtr);\r
-       mmioClose(infoPtr->hMMio, 0);\r
-       if (infoPtr->hRes) {\r
-           FreeResource(infoPtr->hRes);\r
-           infoPtr->hRes = 0;\r
-       }\r
-       if (infoPtr->lpIndex) {\r
-           HeapFree(GetProcessHeap(), 0, infoPtr->lpIndex);\r
-           infoPtr->lpIndex = NULL;\r
-       }\r
-       if (infoPtr->hic) {\r
-           fnIC.fnICClose(infoPtr->hic);\r
-           infoPtr->hic = 0;\r
-       }\r
-       if (infoPtr->inbih) {\r
-           HeapFree(GetProcessHeap(), 0, infoPtr->inbih);\r
-           infoPtr->inbih = NULL;\r
-       }\r
-       if (infoPtr->outbih) {\r
-           HeapFree(GetProcessHeap(), 0, infoPtr->outbih);\r
-           infoPtr->outbih = NULL;\r
-       }\r
-        if( infoPtr->indata )\r
-        {\r
-       HeapFree(GetProcessHeap(), 0, infoPtr->indata);\r
-            infoPtr->indata = NULL;\r
-        }\r
-       if( infoPtr->outdata )\r
-        {\r
-       HeapFree(GetProcessHeap(), 0, infoPtr->outdata);\r
-            infoPtr->outdata = NULL;\r
-        }\r
-       if( infoPtr->hbmPrevFrame )\r
-        {\r
-           DeleteObject(infoPtr->hbmPrevFrame);\r
-            infoPtr->hbmPrevFrame = 0;\r
-        }\r
-       infoPtr->indata = infoPtr->outdata = NULL;\r
-       infoPtr->hWnd = 0;\r
-       infoPtr->hMMio = 0;\r
-\r
-       memset(&infoPtr->mah, 0, sizeof(infoPtr->mah));\r
-       memset(&infoPtr->ash, 0, sizeof(infoPtr->ash));\r
-       infoPtr->nFromFrame = infoPtr->nToFrame = infoPtr->nLoop = infoPtr->currFrame = 0;\r
-    }\r
-    infoPtr->transparentColor = ANIMATE_COLOR_NONE;\r
-}\r
-\r
-static void ANIMATE_TransparentBlt(ANIMATE_INFO* infoPtr, HDC hdcDest, HDC hdcSource)\r
-{\r
-    HDC hdcMask;\r
-    HBITMAP hbmMask;\r
-    HBITMAP hbmOld;\r
-\r
-    /* create a transparency mask */\r
-    hdcMask = CreateCompatibleDC(hdcDest);\r
-    hbmMask = CreateBitmap(infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, 1,1,NULL);\r
-    hbmOld = SelectObject(hdcMask, hbmMask);\r
-\r
-    SetBkColor(hdcSource,infoPtr->transparentColor);\r
-    BitBlt(hdcMask,0,0,infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,hdcSource,0,0,SRCCOPY);\r
-\r
-    /* mask the source bitmap */\r
-    SetBkColor(hdcSource, RGB(0,0,0));\r
-    SetTextColor(hdcSource, RGB(255,255,255));\r
-    BitBlt(hdcSource, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, hdcMask, 0, 0, SRCAND);\r
-\r
-    /* mask the destination bitmap */\r
-    SetBkColor(hdcDest, RGB(255,255,255));\r
-    SetTextColor(hdcDest, RGB(0,0,0));\r
-    BitBlt(hdcDest, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, hdcMask, 0, 0, SRCAND);\r
-\r
-    /* combine source and destination */\r
-    BitBlt(hdcDest,0,0,infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,hdcSource,0,0,SRCPAINT);\r
-\r
-    SelectObject(hdcMask, hbmOld);\r
-    DeleteObject(hbmMask);\r
-    DeleteDC(hdcMask);\r
-}\r
-\r
-static LRESULT ANIMATE_PaintFrame(ANIMATE_INFO* infoPtr, HDC hDC)\r
-{\r
-    void* pBitmapData = NULL;\r
-    LPBITMAPINFO pBitmapInfo = NULL;\r
-\r
-    HDC hdcMem;\r
-    HBITMAP hbmOld;\r
-\r
-    int nOffsetX = 0;\r
-    int nOffsetY = 0;\r
-\r
-    int nWidth;\r
-    int nHeight;\r
-\r
-    if (!hDC || !infoPtr->inbih)\r
-       return TRUE;\r
-\r
-    if (infoPtr->hic )\r
-    {\r
-        pBitmapData = infoPtr->outdata;\r
-        pBitmapInfo = (LPBITMAPINFO)infoPtr->outbih;\r
-\r
-        nWidth = infoPtr->outbih->biWidth;\r
-        nHeight = infoPtr->outbih->biHeight;\r
-    } else\r
-    {\r
-        pBitmapData = infoPtr->indata;\r
-        pBitmapInfo = (LPBITMAPINFO)infoPtr->inbih;\r
-\r
-        nWidth = infoPtr->inbih->biWidth;\r
-        nHeight = infoPtr->inbih->biHeight;\r
-    }\r
-\r
-    if(!infoPtr->hbmPrevFrame)\r
-    {\r
-        infoPtr->hbmPrevFrame=CreateCompatibleBitmap(hDC, nWidth,nHeight );\r
-    }\r
-\r
-    SetDIBits(hDC, infoPtr->hbmPrevFrame, 0, nHeight, pBitmapData, (LPBITMAPINFO)pBitmapInfo, DIB_RGB_COLORS);\r
-\r
-    hdcMem = CreateCompatibleDC(hDC);\r
-    hbmOld = SelectObject(hdcMem, infoPtr->hbmPrevFrame);\r
-\r
-    /*\r
-     * we need to get the transparent color even without ACS_TRANSPARENT,\r
-     * because the style can be changed later on and the color should always\r
-     * be obtained in the first frame\r
-     */\r
-    if(infoPtr->transparentColor == ANIMATE_COLOR_NONE)\r
-    {\r
-        infoPtr->transparentColor = GetPixel(hdcMem,0,0);\r
-    }\r
-\r
-    if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT)\r
-    {\r
-        HDC hdcFinal = CreateCompatibleDC(hDC);\r
-        HBITMAP hbmFinal = CreateCompatibleBitmap(hDC,nWidth, nHeight);\r
-        HBITMAP hbmOld2 = SelectObject(hdcFinal, hbmFinal);\r
-        RECT rect;\r
-\r
-        rect.left = 0;\r
-        rect.top = 0;\r
-        rect.right = nWidth;\r
-        rect.bottom = nHeight;\r
-\r
-        if(!infoPtr->hbrushBG)\r
-            infoPtr->hbrushBG = GetCurrentObject(hDC, OBJ_BRUSH);\r
-\r
-        FillRect(hdcFinal, &rect, infoPtr->hbrushBG);\r
-        ANIMATE_TransparentBlt(infoPtr, hdcFinal, hdcMem);\r
-\r
-        SelectObject(hdcFinal, hbmOld2);\r
-        SelectObject(hdcMem, hbmFinal);\r
-        DeleteDC(hdcFinal);\r
-        DeleteObject(infoPtr->hbmPrevFrame);\r
-        infoPtr->hbmPrevFrame = hbmFinal;\r
-         }\r
-\r
-    if (GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_CENTER)\r
-    {\r
-       RECT rect;\r
-\r
-       GetWindowRect(infoPtr->hWnd, &rect);\r
-       nOffsetX = ((rect.right - rect.left) - nWidth)/2;\r
-       nOffsetY = ((rect.bottom - rect.top) - nHeight)/2;\r
-    }\r
-    BitBlt(hDC, nOffsetX, nOffsetY, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);\r
-\r
-    SelectObject(hdcMem, hbmOld);\r
-    DeleteDC(hdcMem);\r
-    return TRUE;\r
-}\r
-\r
-static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr)\r
-{\r
-    HDC                hDC;\r
-\r
-    TRACE("Drawing frame %d (loop %d)\n", infoPtr->currFrame, infoPtr->nLoop);\r
-\r
-    EnterCriticalSection(&infoPtr->cs);\r
-\r
-    mmioSeek(infoPtr->hMMio, infoPtr->lpIndex[infoPtr->currFrame], SEEK_SET);\r
-    mmioRead(infoPtr->hMMio, infoPtr->indata, infoPtr->ash.dwSuggestedBufferSize);\r
-\r
-    if (infoPtr->hic &&\r
-       fnIC.fnICDecompress(infoPtr->hic, 0, infoPtr->inbih, infoPtr->indata,\r
-                    infoPtr->outbih, infoPtr->outdata) != ICERR_OK) {\r
-       LeaveCriticalSection(&infoPtr->cs);\r
-       WARN("Decompression error\n");\r
-       return FALSE;\r
-    }\r
-\r
-    if ((hDC = GetDC(infoPtr->hWnd)) != 0) {\r
-       ANIMATE_PaintFrame(infoPtr, hDC);\r
-       ReleaseDC(infoPtr->hWnd, hDC);\r
-    }\r
-\r
-    if (infoPtr->currFrame++ >= infoPtr->nToFrame) {\r
-       infoPtr->currFrame = infoPtr->nFromFrame;\r
-       if (infoPtr->nLoop != -1) {\r
-           if (--infoPtr->nLoop == 0) {\r
-               ANIMATE_DoStop(infoPtr);\r
-           }\r
-       }\r
-    }\r
-    LeaveCriticalSection(&infoPtr->cs);\r
-\r
-    return TRUE;\r
-}\r
-\r
-static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_)\r
-{\r
-    ANIMATE_INFO*      infoPtr = (ANIMATE_INFO*)ptr_;\r
-    HDC hDC;\r
-\r
-    if(!infoPtr)\r
-    {\r
-        WARN("animation structure undefined!\n");\r
-        return FALSE;\r
-    }\r
-\r
-    while(1)\r
-    {\r
-        if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT)\r
-        {\r
-            hDC = GetDC(infoPtr->hWnd);\r
-           /* sometimes the animation window will be destroyed in between\r
-            * by the main program, so a ReleaseDC() error msg is possible */\r
-            infoPtr->hbrushBG = (HBRUSH)SendMessageA(GetParent(infoPtr->hWnd),\r
-                                            WM_CTLCOLORSTATIC, (WPARAM)hDC,\r
-                                            (LPARAM)infoPtr->hWnd);\r
-            ReleaseDC(infoPtr->hWnd,hDC);\r
-        }\r
-\r
-        EnterCriticalSection(&infoPtr->cs);\r
-        ANIMATE_DrawFrame(infoPtr);\r
-        LeaveCriticalSection(&infoPtr->cs);\r
-\r
-        /* time is in microseconds, we should convert it to milliseconds */\r
-        Sleep((infoPtr->mah.dwMicroSecPerFrame+500)/1000);\r
-    }\r
-    return TRUE;\r
-}\r
-\r
-static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);\r
-\r
-    /* nothing opened */\r
-    if (!infoPtr->hMMio)\r
-       return FALSE;\r
-\r
-    if (infoPtr->hThread || infoPtr->uTimer) {\r
-       FIXME("Already playing ? what should I do ??\n");\r
-       ANIMATE_DoStop(infoPtr);\r
-    }\r
-\r
-    infoPtr->nFromFrame = (INT)LOWORD(lParam);\r
-    infoPtr->nToFrame   = (INT)HIWORD(lParam);\r
-    infoPtr->nLoop      = (INT)wParam;\r
-\r
-    if (infoPtr->nToFrame == 0xFFFF)\r
-       infoPtr->nToFrame = infoPtr->mah.dwTotalFrames - 1;\r
-\r
-    TRACE("(repeat=%d from=%d to=%d);\n",\r
-         infoPtr->nLoop, infoPtr->nFromFrame, infoPtr->nToFrame);\r
-\r
-    if (infoPtr->nFromFrame >= infoPtr->nToFrame ||\r
-       infoPtr->nToFrame >= infoPtr->mah.dwTotalFrames)\r
-       return FALSE;\r
-\r
-    infoPtr->currFrame = infoPtr->nFromFrame;\r
-\r
-    if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TIMER) {\r
-       TRACE("Using a timer\n");\r
-       /* create a timer to display AVI */\r
-       infoPtr->uTimer = SetTimer(hWnd, 1, infoPtr->mah.dwMicroSecPerFrame / 1000, NULL);\r
-    } else {\r
-        DWORD threadID;\r
-\r
-       TRACE("Using an animation thread\n");\r
-        infoPtr->hThread = CreateThread(0,0,ANIMATE_AnimationThread,(LPVOID)infoPtr, 0, &threadID);\r
-        if(!infoPtr->hThread)\r
-        {\r
-           ERR("Could not create animation thread!\n");\r
-           return FALSE;\r
-    }\r
-\r
-    }\r
-\r
-    ANIMATE_Notify(infoPtr, ACN_START);\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static BOOL ANIMATE_GetAviInfo(ANIMATE_INFO *infoPtr)\r
-{\r
-    MMCKINFO           ckMainRIFF;\r
-    MMCKINFO           mmckHead;\r
-    MMCKINFO           mmckList;\r
-    MMCKINFO           mmckInfo;\r
-    DWORD              numFrame;\r
-    DWORD              insize;\r
-\r
-    if (mmioDescend(infoPtr->hMMio, &ckMainRIFF, NULL, 0) != 0) {\r
-       WARN("Can't find 'RIFF' chunk\n");\r
-       return FALSE;\r
-    }\r
-\r
-    if ((ckMainRIFF.ckid != FOURCC_RIFF) ||\r
-       (ckMainRIFF.fccType != mmioFOURCC('A', 'V', 'I', ' '))) {\r
-       WARN("Can't find 'AVI ' chunk\n");\r
-       return FALSE;\r
-    }\r
-\r
-    mmckHead.fccType = mmioFOURCC('h', 'd', 'r', 'l');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) {\r
-       WARN("Can't find 'hdrl' list\n");\r
-       return FALSE;\r
-    }\r
-\r
-    mmckInfo.ckid = mmioFOURCC('a', 'v', 'i', 'h');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) {\r
-       WARN("Can't find 'avih' chunk\n");\r
-       return FALSE;\r
-    }\r
-\r
-    mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->mah, sizeof(infoPtr->mah));\r
-\r
-    TRACE("mah.dwMicroSecPerFrame=%ld\n",      infoPtr->mah.dwMicroSecPerFrame);\r
-    TRACE("mah.dwMaxBytesPerSec=%ld\n",        infoPtr->mah.dwMaxBytesPerSec);\r
-    TRACE("mah.dwPaddingGranularity=%ld\n",    infoPtr->mah.dwPaddingGranularity);\r
-    TRACE("mah.dwFlags=%ld\n",                         infoPtr->mah.dwFlags);\r
-    TRACE("mah.dwTotalFrames=%ld\n",           infoPtr->mah.dwTotalFrames);\r
-    TRACE("mah.dwInitialFrames=%ld\n",                 infoPtr->mah.dwInitialFrames);\r
-    TRACE("mah.dwStreams=%ld\n",               infoPtr->mah.dwStreams);\r
-    TRACE("mah.dwSuggestedBufferSize=%ld\n",   infoPtr->mah.dwSuggestedBufferSize);\r
-    TRACE("mah.dwWidth=%ld\n",                         infoPtr->mah.dwWidth);\r
-    TRACE("mah.dwHeight=%ld\n",                infoPtr->mah.dwHeight);\r
-\r
-    mmioAscend(infoPtr->hMMio, &mmckInfo, 0);\r
-\r
-    mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) {\r
-       WARN("Can't find 'strl' list\n");\r
-       return FALSE;\r
-    }\r
-\r
-    mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'h');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) {\r
-       WARN("Can't find 'strh' chunk\n");\r
-       return FALSE;\r
-    }\r
-\r
-    mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->ash, sizeof(infoPtr->ash));\r
-\r
-    TRACE("ash.fccType='%c%c%c%c'\n",          LOBYTE(LOWORD(infoPtr->ash.fccType)),\r
-                                               HIBYTE(LOWORD(infoPtr->ash.fccType)),\r
-                                               LOBYTE(HIWORD(infoPtr->ash.fccType)),\r
-                                               HIBYTE(HIWORD(infoPtr->ash.fccType)));\r
-    TRACE("ash.fccHandler='%c%c%c%c'\n",       LOBYTE(LOWORD(infoPtr->ash.fccHandler)),\r
-                                               HIBYTE(LOWORD(infoPtr->ash.fccHandler)),\r
-                                               LOBYTE(HIWORD(infoPtr->ash.fccHandler)),\r
-                                               HIBYTE(HIWORD(infoPtr->ash.fccHandler)));\r
-    TRACE("ash.dwFlags=%ld\n",                         infoPtr->ash.dwFlags);\r
-    TRACE("ash.wPriority=%d\n",                infoPtr->ash.wPriority);\r
-    TRACE("ash.wLanguage=%d\n",                infoPtr->ash.wLanguage);\r
-    TRACE("ash.dwInitialFrames=%ld\n",                 infoPtr->ash.dwInitialFrames);\r
-    TRACE("ash.dwScale=%ld\n",                         infoPtr->ash.dwScale);\r
-    TRACE("ash.dwRate=%ld\n",                  infoPtr->ash.dwRate);\r
-    TRACE("ash.dwStart=%ld\n",                         infoPtr->ash.dwStart);\r
-    TRACE("ash.dwLength=%ld\n",                infoPtr->ash.dwLength);\r
-    TRACE("ash.dwSuggestedBufferSize=%ld\n",   infoPtr->ash.dwSuggestedBufferSize);\r
-    TRACE("ash.dwQuality=%ld\n",               infoPtr->ash.dwQuality);\r
-    TRACE("ash.dwSampleSize=%ld\n",            infoPtr->ash.dwSampleSize);\r
-    TRACE("ash.rcFrame=(%d,%d,%d,%d)\n",       infoPtr->ash.rcFrame.top, infoPtr->ash.rcFrame.left,\r
-         infoPtr->ash.rcFrame.bottom, infoPtr->ash.rcFrame.right);\r
-\r
-    mmioAscend(infoPtr->hMMio, &mmckInfo, 0);\r
-\r
-    mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'f');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) {\r
-       WARN("Can't find 'strh' chunk\n");\r
-       return FALSE;\r
-    }\r
-\r
-    infoPtr->inbih = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);\r
-    if (!infoPtr->inbih) {\r
-       WARN("Can't alloc input BIH\n");\r
-       return FALSE;\r
-    }\r
-\r
-    mmioRead(infoPtr->hMMio, (LPSTR)infoPtr->inbih, mmckInfo.cksize);\r
-\r
-    TRACE("bih.biSize=%ld\n",          infoPtr->inbih->biSize);\r
-    TRACE("bih.biWidth=%ld\n",                 infoPtr->inbih->biWidth);\r
-    TRACE("bih.biHeight=%ld\n",        infoPtr->inbih->biHeight);\r
-    TRACE("bih.biPlanes=%d\n",                 infoPtr->inbih->biPlanes);\r
-    TRACE("bih.biBitCount=%d\n",       infoPtr->inbih->biBitCount);\r
-    TRACE("bih.biCompression=%ld\n",   infoPtr->inbih->biCompression);\r
-    TRACE("bih.biSizeImage=%ld\n",     infoPtr->inbih->biSizeImage);\r
-    TRACE("bih.biXPelsPerMeter=%ld\n",         infoPtr->inbih->biXPelsPerMeter);\r
-    TRACE("bih.biYPelsPerMeter=%ld\n",         infoPtr->inbih->biYPelsPerMeter);\r
-    TRACE("bih.biClrUsed=%ld\n",       infoPtr->inbih->biClrUsed);\r
-    TRACE("bih.biClrImportant=%ld\n",  infoPtr->inbih->biClrImportant);\r
-\r
-    mmioAscend(infoPtr->hMMio, &mmckInfo, 0);\r
-\r
-    mmioAscend(infoPtr->hMMio, &mmckList, 0);\r
-\r
-#if 0\r
-    /* an AVI has 0 or 1 video stream, and to be animated should not contain\r
-     * an audio stream, so only one strl is allowed\r
-     */\r
-    mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) {\r
-       WARN("There should be a single 'strl' list\n");\r
-       return FALSE;\r
-    }\r
-#endif\r
-\r
-    mmioAscend(infoPtr->hMMio, &mmckHead, 0);\r
-\r
-    /* no need to read optional JUNK chunk */\r
-\r
-    mmckList.fccType = mmioFOURCC('m', 'o', 'v', 'i');\r
-    if (mmioDescend(infoPtr->hMMio, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) {\r
-       WARN("Can't find 'movi' list\n");\r
-       return FALSE;\r
-    }\r
-\r
-    /* FIXME: should handle the 'rec ' LIST when present */\r
-\r
-    infoPtr->lpIndex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,\r
-                                infoPtr->mah.dwTotalFrames * sizeof(DWORD));\r
-    if (!infoPtr->lpIndex) {\r
-       WARN("Can't alloc index array\n");\r
-       return FALSE;\r
-    }\r
-\r
-    numFrame = insize = 0;\r
-    while (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, 0) == 0 &&\r
-          numFrame < infoPtr->mah.dwTotalFrames) {\r
-       infoPtr->lpIndex[numFrame] = mmckInfo.dwDataOffset;\r
-       if (insize < mmckInfo.cksize)\r
-           insize = mmckInfo.cksize;\r
-       numFrame++;\r
-       mmioAscend(infoPtr->hMMio, &mmckInfo, 0);\r
-    }\r
-    if (numFrame != infoPtr->mah.dwTotalFrames) {\r
-       WARN("Found %ld frames (/%ld)\n", numFrame, infoPtr->mah.dwTotalFrames);\r
-       return FALSE;\r
-    }\r
-    if (insize > infoPtr->ash.dwSuggestedBufferSize) {\r
-       WARN("insize=%ld suggestedSize=%ld\n", insize, infoPtr->ash.dwSuggestedBufferSize);\r
-       infoPtr->ash.dwSuggestedBufferSize = insize;\r
-    }\r
-\r
-    infoPtr->indata = HeapAlloc(GetProcessHeap(), 0, infoPtr->ash.dwSuggestedBufferSize);\r
-    if (!infoPtr->indata) {\r
-       WARN("Can't alloc input buffer\n");\r
-       return FALSE;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static BOOL    ANIMATE_GetAviCodec(ANIMATE_INFO *infoPtr)\r
-{\r
-    DWORD      outSize;\r
-\r
-    /* check uncompressed AVI */\r
-    if ((infoPtr->ash.fccHandler == mmioFOURCC('D', 'I', 'B', ' ')) ||\r
-       (infoPtr->ash.fccHandler == mmioFOURCC('R', 'L', 'E', ' ')) ||\r
-       (infoPtr->ash.fccHandler == mmioFOURCC(0, 0, 0, 0)))\r
-    {\r
-        infoPtr->hic = 0;\r
-       return TRUE;\r
-    }\r
-\r
-    /* try to get a decompressor for that type */\r
-    infoPtr->hic = fnIC.fnICOpen(ICTYPE_VIDEO, infoPtr->ash.fccHandler, ICMODE_DECOMPRESS);\r
-    if (!infoPtr->hic) {\r
-       WARN("Can't load codec for the file\n");\r
-       return FALSE;\r
-    }\r
-\r
-    outSize = fnIC.fnICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT,\r
-                           (DWORD)infoPtr->inbih, 0L);\r
-\r
-    infoPtr->outbih = HeapAlloc(GetProcessHeap(), 0, outSize);\r
-    if (!infoPtr->outbih) {\r
-       WARN("Can't alloc output BIH\n");\r
-       return FALSE;\r
-    }\r
-\r
-    if (fnIC.fnICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT,\r
-                     (DWORD)infoPtr->inbih, (DWORD)infoPtr->outbih) != outSize) {\r
-       WARN("Can't get output BIH\n");\r
-       return FALSE;\r
-    }\r
-\r
-    infoPtr->outdata = HeapAlloc(GetProcessHeap(), 0, infoPtr->outbih->biSizeImage);\r
-    if (!infoPtr->outdata) {\r
-       WARN("Can't alloc output buffer\n");\r
-       return FALSE;\r
-    }\r
-\r
-    if (fnIC.fnICSendMessage(infoPtr->hic, ICM_DECOMPRESS_BEGIN,\r
-                     (DWORD)infoPtr->inbih, (DWORD)infoPtr->outbih) != ICERR_OK) {\r
-       WARN("Can't begin decompression\n");\r
-       return FALSE;\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-static LRESULT ANIMATE_OpenA(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);\r
-    HINSTANCE hInstance = (HINSTANCE)wParam;\r
-\r
-    ANIMATE_Free(infoPtr);\r
-    infoPtr->hWnd = hWnd;\r
-\r
-    if (!lParam) {\r
-       TRACE("Closing avi!\n");\r
-        /* installer of thebat! v1.62 requires FALSE here */\r
-       return (infoPtr->hMMio != 0);\r
-    }\r
-\r
-    if (!hInstance)\r
-       hInstance = (HINSTANCE)GetWindowLongA(hWnd, GWL_HINSTANCE);\r
-\r
-    if (HIWORD(lParam)) {\r
-       TRACE("(\"%s\");\n", (LPSTR)lParam);\r
-\r
-       if (!ANIMATE_LoadResA(infoPtr, hInstance, (LPSTR)lParam)) {\r
-           TRACE("No AVI resource found!\n");\r
-           if (!ANIMATE_LoadFileA(infoPtr, (LPSTR)lParam)) {\r
-               WARN("No AVI file found!\n");\r
-               return FALSE;\r
-           }\r
-       }\r
-    } else {\r
-       TRACE("(%u);\n", (WORD)LOWORD(lParam));\r
-\r
-       if (!ANIMATE_LoadResA(infoPtr, hInstance,\r
-                             MAKEINTRESOURCEA((INT)lParam))) {\r
-           WARN("No AVI resource found!\n");\r
-           return FALSE;\r
-       }\r
-    }\r
-\r
-    if (!ANIMATE_GetAviInfo(infoPtr)) {\r
-       WARN("Can't get AVI information\n");\r
-       ANIMATE_Free(infoPtr);\r
-       return FALSE;\r
-    }\r
-\r
-    if (!ANIMATE_GetAviCodec(infoPtr)) {\r
-       WARN("Can't get AVI Codec\n");\r
-       ANIMATE_Free(infoPtr);\r
-       return FALSE;\r
-    }\r
-\r
-    if (!GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) {\r
-       SetWindowPos(hWnd, 0, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight,\r
-                    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);\r
-    }\r
-\r
-    if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_AUTOPLAY) {\r
-       return ANIMATE_Play(hWnd, -1, (LPARAM)MAKELONG(0, infoPtr->mah.dwTotalFrames-1));\r
-    }\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-/* << ANIMATE_Open32W >> */\r
-\r
-static LRESULT ANIMATE_Stop(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);\r
-\r
-    /* nothing opened */\r
-    if (!infoPtr->hMMio)\r
-       return FALSE;\r
-\r
-    ANIMATE_DoStop(infoPtr);\r
-    return TRUE;\r
-}\r
-\r
-\r
-static LRESULT ANIMATE_Create(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    ANIMATE_INFO*      infoPtr;\r
-\r
-    if (!fnIC.hModule) /* FIXME: not thread safe */\r
-    {\r
-       /* since there's a circular dep between msvfw32 and comctl32, we could either:\r
-        * - fix the build chain to allow this circular dep\r
-        * - handle it by hand\r
-        * AJ wants the latter :-(\r
-        */\r
-       fnIC.hModule = LoadLibraryA("msvfw32.dll");\r
-       if (!fnIC.hModule) return FALSE;\r
-\r
-       fnIC.fnICOpen        = (void*)GetProcAddress(fnIC.hModule, "ICOpen");\r
-       fnIC.fnICClose       = (void*)GetProcAddress(fnIC.hModule, "ICClose");\r
-       fnIC.fnICSendMessage = (void*)GetProcAddress(fnIC.hModule, "ICSendMessage");\r
-       fnIC.fnICDecompress  = (void*)GetProcAddress(fnIC.hModule, "ICDecompress");\r
-    }\r
-\r
-    /* allocate memory for info structure */\r
-    infoPtr = (ANIMATE_INFO *)Alloc(sizeof(ANIMATE_INFO));\r
-    if (!infoPtr) {\r
-       ERR("could not allocate info memory!\n");\r
-       return 0;\r
-    }\r
-\r
-    TRACE("Animate style=0x%08lx, parent=%08lx\n", GetWindowLongA(hWnd, GWL_STYLE), (DWORD)GetParent(hWnd));\r
-\r
-    /* store crossref hWnd <-> info structure */\r
-    SetWindowLongA(hWnd, 0, (DWORD)infoPtr);\r
-    infoPtr->hWnd = hWnd;\r
-    infoPtr->transparentColor = ANIMATE_COLOR_NONE;\r
-    infoPtr->hbmPrevFrame = 0;\r
-\r
-    InitializeCriticalSection(&infoPtr->cs);\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT ANIMATE_Destroy(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);\r
-\r
-\r
-    /* free avi data */\r
-    ANIMATE_Free(infoPtr);\r
-\r
-    /* free animate info data */\r
-    Free(infoPtr);\r
-    SetWindowLongA(hWnd, 0, 0);\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT ANIMATE_EraseBackground(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    RECT rect;\r
-    HBRUSH hBrush = 0;\r
-\r
-    if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)\r
-    {\r
-        hBrush = (HBRUSH)SendMessageA(GetParent(hWnd),WM_CTLCOLORSTATIC,\r
-                                     wParam, (LPARAM)hWnd);\r
-    }\r
-\r
-    GetClientRect(hWnd, &rect);\r
-    FillRect((HDC)wParam, &rect, hBrush ? hBrush : GetCurrentObject((HDC)wParam, OBJ_BRUSH));\r
-\r
-    return TRUE;\r
-}\r
-\r
-static LRESULT WINAPI ANIMATE_Size(HWND hWnd, WPARAM wParam, LPARAM lParam)\r
-{\r
-    if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) {\r
-       InvalidateRect(hWnd, NULL, TRUE);\r
-    }\r
-    return TRUE;\r
-}\r
-\r
-static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-    TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);\r
-    if (!ANIMATE_GetInfoPtr(hWnd) && (uMsg != WM_NCCREATE))\r
-       return DefWindowProcA(hWnd, uMsg, wParam, lParam);\r
-    switch (uMsg)\r
-    {\r
-    case ACM_OPENA:\r
-       return ANIMATE_OpenA(hWnd, wParam, lParam);\r
-\r
-       /*      case ACM_OPEN32W: FIXME!! */\r
-       /*          return ANIMATE_Open32W(hWnd, wParam, lParam); */\r
-\r
-    case ACM_PLAY:\r
-       return ANIMATE_Play(hWnd, wParam, lParam);\r
-\r
-    case ACM_STOP:\r
-       return ANIMATE_Stop(hWnd, wParam, lParam);\r
-\r
-    case WM_NCCREATE:\r
-       ANIMATE_Create(hWnd, wParam, lParam);\r
-       return DefWindowProcA(hWnd, uMsg, wParam, lParam);\r
-\r
-    case WM_NCHITTEST:\r
-       return HTTRANSPARENT;\r
-\r
-    case WM_DESTROY:\r
-       ANIMATE_Destroy(hWnd, wParam, lParam);\r
-       return DefWindowProcA(hWnd, uMsg, wParam, lParam);\r
-\r
-    case WM_ERASEBKGND:\r
-       ANIMATE_EraseBackground(hWnd, wParam, lParam);\r
-       break;\r
-\r
-    /* case WM_STYLECHANGED: FIXME shall we do something ?? */\r
-\r
-    case WM_TIMER:\r
-       if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)\r
-        {\r
-            ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd);\r
-            infoPtr->hbrushBG = (HBRUSH)SendMessageA(GetParent(hWnd),\r
-                                                    WM_CTLCOLORSTATIC,\r
-                                                    wParam, (LPARAM)hWnd);\r
-        }\r
-       return ANIMATE_DrawFrame(ANIMATE_GetInfoPtr(hWnd));\r
-\r
-    case WM_CLOSE:\r
-       ANIMATE_Free(ANIMATE_GetInfoPtr(hWnd));\r
-       return TRUE;\r
-\r
-    case WM_PAINT:\r
-        {\r
-            ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd);\r
-\r
-            /* the animation isn't playing, don't paint */\r
-           if(!infoPtr->uTimer && !infoPtr->hThread)\r
-               /* default paint handling */\r
-               return DefWindowProcA(hWnd, uMsg, wParam, lParam);\r
-\r
-            if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)\r
-                infoPtr->hbrushBG = (HBRUSH)SendMessageA(GetParent(hWnd),\r
-                                                        WM_CTLCOLORSTATIC,\r
-                                                        wParam, (LPARAM)hWnd);\r
-\r
-            if (wParam)\r
-            {\r
-                EnterCriticalSection(&infoPtr->cs);\r
-                ANIMATE_PaintFrame(infoPtr, (HDC)wParam);\r
-                LeaveCriticalSection(&infoPtr->cs);\r
-            }\r
-            else\r
-            {\r
-               PAINTSTRUCT ps;\r
-               HDC hDC = BeginPaint(hWnd, &ps);\r
-\r
-                EnterCriticalSection(&infoPtr->cs);\r
-                ANIMATE_PaintFrame(infoPtr, hDC);\r
-                LeaveCriticalSection(&infoPtr->cs);\r
-\r
-               EndPaint(hWnd, &ps);\r
-           }\r
-        }\r
-       break;\r
-\r
-    case WM_SIZE:\r
-       ANIMATE_Size(hWnd, wParam, lParam);\r
-       return DefWindowProcA(hWnd, uMsg, wParam, lParam);\r
-\r
-    default:\r
-       if ((uMsg >= WM_USER) && (uMsg < WM_APP))\r
-           ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam);\r
-\r
-       return DefWindowProcA(hWnd, uMsg, wParam, lParam);\r
-    }\r
-    return 0;\r
-}\r
-\r
-void ANIMATE_Register(void)\r
-{\r
-    WNDCLASSA wndClass;\r
-\r
-    ZeroMemory(&wndClass, sizeof(WNDCLASSA));\r
-    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;\r
-    wndClass.lpfnWndProc   = (WNDPROC)ANIMATE_WindowProc;\r
-    wndClass.cbClsExtra    = 0;\r
-    wndClass.cbWndExtra    = sizeof(ANIMATE_INFO *);\r
-    wndClass.hCursor       = LoadCursorA(0, (LPSTR)IDC_ARROW);\r
-    wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);\r
-    wndClass.lpszClassName = ANIMATE_CLASSA;\r
-\r
-    RegisterClassA(&wndClass);\r
-}\r
-\r
-\r
-void ANIMATE_Unregister(void)\r
-{\r
-    UnregisterClassA(ANIMATE_CLASSA, NULL);\r
-}\r
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+/*
+ * Animation control
+ *
+ * Copyright 1998, 1999 Eric Kohl
+ *                1999 Eric Pouech
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * NOTES
+ *   I will only improve this control once in a while.
+ *     Eric <ekohl@abo.rhein-zeitung.de>
+ *
+ * TODO:
+ *   - check for the 'rec ' list in some AVI files
+ *   - concurrent access to infoPtr
+ */
+
+#define COM_NO_WINDOWS_H
+#include <stdarg.h>
+#include <string.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "commctrl.h"
+#include "vfw.h"
+#include "mmsystem.h"
+#include "comctl32.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(animate);
+
+static struct {
+    HMODULE    hModule;
+    HIC         (WINAPI *fnICOpen)(DWORD, DWORD, UINT);
+    LRESULT     (WINAPI *fnICClose)(HIC);
+    LRESULT     (WINAPI *fnICSendMessage)(HIC, UINT, DWORD, DWORD);
+    DWORD       (WINAPIV *fnICDecompress)(HIC,DWORD,LPBITMAPINFOHEADER,LPVOID,LPBITMAPINFOHEADER,LPVOID);
+} fnIC;
+
+typedef struct
+{
+   /* reference to input stream (file or resource) */
+   HGLOBAL             hRes;
+   HMMIO               hMMio;  /* handle to mmio stream */
+   HWND                        hWnd;
+   /* information on the loaded AVI file */
+   MainAVIHeader       mah;
+   AVIStreamHeader     ash;
+   LPBITMAPINFOHEADER  inbih;
+   LPDWORD             lpIndex;
+   /* data for the decompressor */
+   HIC                 hic;
+   LPBITMAPINFOHEADER  outbih;
+   LPVOID              indata;
+   LPVOID              outdata;
+   /* data for the background mechanism */
+   CRITICAL_SECTION    cs;
+   HANDLE              hThread;
+   UINT                        uTimer;
+   /* data for playing the file */
+   int                 nFromFrame;
+   int                 nToFrame;
+   int                 nLoop;
+   int                 currFrame;
+   /* tranparency info*/
+   COLORREF            transparentColor;
+   HBRUSH              hbrushBG;
+   HBITMAP             hbmPrevFrame;
+} ANIMATE_INFO;
+
+#define ANIMATE_GetInfoPtr(hWnd) ((ANIMATE_INFO *)GetWindowLongA(hWnd, 0))
+#define ANIMATE_COLOR_NONE     0xffffffff
+
+static void ANIMATE_Notify(ANIMATE_INFO* infoPtr, UINT notif)
+{
+    SendMessageA(GetParent(infoPtr->hWnd), WM_COMMAND,
+                MAKEWPARAM(GetDlgCtrlID(infoPtr->hWnd), notif),
+                (LPARAM)infoPtr->hWnd);
+}
+
+static BOOL ANIMATE_LoadResA(ANIMATE_INFO *infoPtr, HINSTANCE hInst, LPSTR lpName)
+{
+    HRSRC      hrsrc;
+    MMIOINFO   mminfo;
+    LPVOID     lpAvi;
+
+    hrsrc = FindResourceA(hInst, lpName, "AVI");
+    if (!hrsrc)
+       return FALSE;
+
+    infoPtr->hRes = LoadResource(hInst, hrsrc);
+    if (!infoPtr->hRes)
+       return FALSE;
+
+    lpAvi = LockResource(infoPtr->hRes);
+    if (!lpAvi)
+       return FALSE;
+
+    memset(&mminfo, 0, sizeof(mminfo));
+    mminfo.fccIOProc = FOURCC_MEM;
+    mminfo.pchBuffer = (LPSTR)lpAvi;
+    mminfo.cchBuffer = SizeofResource(hInst, hrsrc);
+    infoPtr->hMMio = mmioOpenA(NULL, &mminfo, MMIO_READ);
+    if (!infoPtr->hMMio) {
+       GlobalFree((HGLOBAL)lpAvi);
+       return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static BOOL ANIMATE_LoadFileA(ANIMATE_INFO *infoPtr, LPSTR lpName)
+{
+    infoPtr->hMMio = mmioOpenA((LPSTR)lpName, NULL,
+                              MMIO_ALLOCBUF | MMIO_READ | MMIO_DENYWRITE);
+
+    if (!infoPtr->hMMio)
+       return FALSE;
+
+    return TRUE;
+}
+
+
+static LRESULT ANIMATE_DoStop(ANIMATE_INFO *infoPtr)
+{
+    EnterCriticalSection(&infoPtr->cs);
+
+    /* should stop playing */
+    if (infoPtr->hThread)
+    {
+        if (!TerminateThread(infoPtr->hThread,0))
+            WARN("could not destroy animation thread!\n");
+           infoPtr->hThread = 0;
+    }
+    if (infoPtr->uTimer) {
+       KillTimer(infoPtr->hWnd, infoPtr->uTimer);
+       infoPtr->uTimer = 0;
+    }
+
+    LeaveCriticalSection(&infoPtr->cs);
+
+    ANIMATE_Notify(infoPtr, ACN_STOP);
+
+    return TRUE;
+}
+
+
+static void ANIMATE_Free(ANIMATE_INFO *infoPtr)
+{
+    if (infoPtr->hMMio) {
+       ANIMATE_DoStop(infoPtr);
+       mmioClose(infoPtr->hMMio, 0);
+       if (infoPtr->hRes) {
+           FreeResource(infoPtr->hRes);
+           infoPtr->hRes = 0;
+       }
+       if (infoPtr->lpIndex) {
+           HeapFree(GetProcessHeap(), 0, infoPtr->lpIndex);
+           infoPtr->lpIndex = NULL;
+       }
+       if (infoPtr->hic) {
+           fnIC.fnICClose(infoPtr->hic);
+           infoPtr->hic = 0;
+       }
+       if (infoPtr->inbih) {
+           HeapFree(GetProcessHeap(), 0, infoPtr->inbih);
+           infoPtr->inbih = NULL;
+       }
+       if (infoPtr->outbih) {
+           HeapFree(GetProcessHeap(), 0, infoPtr->outbih);
+           infoPtr->outbih = NULL;
+       }
+        if( infoPtr->indata )
+        {
+       HeapFree(GetProcessHeap(), 0, infoPtr->indata);
+            infoPtr->indata = NULL;
+        }
+       if( infoPtr->outdata )
+        {
+       HeapFree(GetProcessHeap(), 0, infoPtr->outdata);
+            infoPtr->outdata = NULL;
+        }
+       if( infoPtr->hbmPrevFrame )
+        {
+           DeleteObject(infoPtr->hbmPrevFrame);
+            infoPtr->hbmPrevFrame = 0;
+        }
+       infoPtr->indata = infoPtr->outdata = NULL;
+       infoPtr->hWnd = 0;
+       infoPtr->hMMio = 0;
+
+       memset(&infoPtr->mah, 0, sizeof(infoPtr->mah));
+       memset(&infoPtr->ash, 0, sizeof(infoPtr->ash));
+       infoPtr->nFromFrame = infoPtr->nToFrame = infoPtr->nLoop = infoPtr->currFrame = 0;
+    }
+    infoPtr->transparentColor = ANIMATE_COLOR_NONE;
+}
+
+static void ANIMATE_TransparentBlt(ANIMATE_INFO* infoPtr, HDC hdcDest, HDC hdcSource)
+{
+    HDC hdcMask;
+    HBITMAP hbmMask;
+    HBITMAP hbmOld;
+
+    /* create a transparency mask */
+    hdcMask = CreateCompatibleDC(hdcDest);
+    hbmMask = CreateBitmap(infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, 1,1,NULL);
+    hbmOld = SelectObject(hdcMask, hbmMask);
+
+    SetBkColor(hdcSource,infoPtr->transparentColor);
+    BitBlt(hdcMask,0,0,infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,hdcSource,0,0,SRCCOPY);
+
+    /* mask the source bitmap */
+    SetBkColor(hdcSource, RGB(0,0,0));
+    SetTextColor(hdcSource, RGB(255,255,255));
+    BitBlt(hdcSource, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, hdcMask, 0, 0, SRCAND);
+
+    /* mask the destination bitmap */
+    SetBkColor(hdcDest, RGB(255,255,255));
+    SetTextColor(hdcDest, RGB(0,0,0));
+    BitBlt(hdcDest, 0, 0, infoPtr->inbih->biWidth, infoPtr->inbih->biHeight, hdcMask, 0, 0, SRCAND);
+
+    /* combine source and destination */
+    BitBlt(hdcDest,0,0,infoPtr->inbih->biWidth, infoPtr->inbih->biHeight,hdcSource,0,0,SRCPAINT);
+
+    SelectObject(hdcMask, hbmOld);
+    DeleteObject(hbmMask);
+    DeleteDC(hdcMask);
+}
+
+static LRESULT ANIMATE_PaintFrame(ANIMATE_INFO* infoPtr, HDC hDC)
+{
+    void* pBitmapData = NULL;
+    LPBITMAPINFO pBitmapInfo = NULL;
+
+    HDC hdcMem;
+    HBITMAP hbmOld;
+
+    int nOffsetX = 0;
+    int nOffsetY = 0;
+
+    int nWidth;
+    int nHeight;
+
+    if (!hDC || !infoPtr->inbih)
+       return TRUE;
+
+    if (infoPtr->hic )
+    {
+        pBitmapData = infoPtr->outdata;
+        pBitmapInfo = (LPBITMAPINFO)infoPtr->outbih;
+
+        nWidth = infoPtr->outbih->biWidth;
+        nHeight = infoPtr->outbih->biHeight;
+    } else
+    {
+        pBitmapData = infoPtr->indata;
+        pBitmapInfo = (LPBITMAPINFO)infoPtr->inbih;
+
+        nWidth = infoPtr->inbih->biWidth;
+        nHeight = infoPtr->inbih->biHeight;
+    }
+
+    if(!infoPtr->hbmPrevFrame)
+    {
+        infoPtr->hbmPrevFrame=CreateCompatibleBitmap(hDC, nWidth,nHeight );
+    }
+
+    SetDIBits(hDC, infoPtr->hbmPrevFrame, 0, nHeight, pBitmapData, (LPBITMAPINFO)pBitmapInfo, DIB_RGB_COLORS);
+
+    hdcMem = CreateCompatibleDC(hDC);
+    hbmOld = SelectObject(hdcMem, infoPtr->hbmPrevFrame);
+
+    /*
+     * we need to get the transparent color even without ACS_TRANSPARENT,
+     * because the style can be changed later on and the color should always
+     * be obtained in the first frame
+     */
+    if(infoPtr->transparentColor == ANIMATE_COLOR_NONE)
+    {
+        infoPtr->transparentColor = GetPixel(hdcMem,0,0);
+    }
+
+    if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT)
+    {
+        HDC hdcFinal = CreateCompatibleDC(hDC);
+        HBITMAP hbmFinal = CreateCompatibleBitmap(hDC,nWidth, nHeight);
+        HBITMAP hbmOld2 = SelectObject(hdcFinal, hbmFinal);
+        RECT rect;
+
+        rect.left = 0;
+        rect.top = 0;
+        rect.right = nWidth;
+        rect.bottom = nHeight;
+
+        if(!infoPtr->hbrushBG)
+            infoPtr->hbrushBG = GetCurrentObject(hDC, OBJ_BRUSH);
+
+        FillRect(hdcFinal, &rect, infoPtr->hbrushBG);
+        ANIMATE_TransparentBlt(infoPtr, hdcFinal, hdcMem);
+
+        SelectObject(hdcFinal, hbmOld2);
+        SelectObject(hdcMem, hbmFinal);
+        DeleteDC(hdcFinal);
+        DeleteObject(infoPtr->hbmPrevFrame);
+        infoPtr->hbmPrevFrame = hbmFinal;
+         }
+
+    if (GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_CENTER)
+    {
+       RECT rect;
+
+       GetWindowRect(infoPtr->hWnd, &rect);
+       nOffsetX = ((rect.right - rect.left) - nWidth)/2;
+       nOffsetY = ((rect.bottom - rect.top) - nHeight)/2;
+    }
+    BitBlt(hDC, nOffsetX, nOffsetY, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);
+
+    SelectObject(hdcMem, hbmOld);
+    DeleteDC(hdcMem);
+    return TRUE;
+}
+
+static LRESULT ANIMATE_DrawFrame(ANIMATE_INFO* infoPtr)
+{
+    HDC                hDC;
+
+    TRACE("Drawing frame %d (loop %d)\n", infoPtr->currFrame, infoPtr->nLoop);
+
+    EnterCriticalSection(&infoPtr->cs);
+
+    mmioSeek(infoPtr->hMMio, infoPtr->lpIndex[infoPtr->currFrame], SEEK_SET);
+    mmioRead(infoPtr->hMMio, infoPtr->indata, infoPtr->ash.dwSuggestedBufferSize);
+
+    if (infoPtr->hic &&
+       fnIC.fnICDecompress(infoPtr->hic, 0, infoPtr->inbih, infoPtr->indata,
+                    infoPtr->outbih, infoPtr->outdata) != ICERR_OK) {
+       LeaveCriticalSection(&infoPtr->cs);
+       WARN("Decompression error\n");
+       return FALSE;
+    }
+
+    if ((hDC = GetDC(infoPtr->hWnd)) != 0) {
+       ANIMATE_PaintFrame(infoPtr, hDC);
+       ReleaseDC(infoPtr->hWnd, hDC);
+    }
+
+    if (infoPtr->currFrame++ >= infoPtr->nToFrame) {
+       infoPtr->currFrame = infoPtr->nFromFrame;
+       if (infoPtr->nLoop != -1) {
+           if (--infoPtr->nLoop == 0) {
+               ANIMATE_DoStop(infoPtr);
+           }
+       }
+    }
+    LeaveCriticalSection(&infoPtr->cs);
+
+    return TRUE;
+}
+
+static DWORD CALLBACK ANIMATE_AnimationThread(LPVOID ptr_)
+{
+    ANIMATE_INFO*      infoPtr = (ANIMATE_INFO*)ptr_;
+    HDC hDC;
+
+    if(!infoPtr)
+    {
+        WARN("animation structure undefined!\n");
+        return FALSE;
+    }
+
+    while(1)
+    {
+        if(GetWindowLongA(infoPtr->hWnd, GWL_STYLE) & ACS_TRANSPARENT)
+        {
+            hDC = GetDC(infoPtr->hWnd);
+           /* sometimes the animation window will be destroyed in between
+            * by the main program, so a ReleaseDC() error msg is possible */
+            infoPtr->hbrushBG = (HBRUSH)SendMessageA(GetParent(infoPtr->hWnd),
+                                            WM_CTLCOLORSTATIC, (WPARAM)hDC,
+                                            (LPARAM)infoPtr->hWnd);
+            ReleaseDC(infoPtr->hWnd,hDC);
+        }
+
+        EnterCriticalSection(&infoPtr->cs);
+        ANIMATE_DrawFrame(infoPtr);
+        LeaveCriticalSection(&infoPtr->cs);
+
+        /* time is in microseconds, we should convert it to milliseconds */
+        Sleep((infoPtr->mah.dwMicroSecPerFrame+500)/1000);
+    }
+    return TRUE;
+}
+
+static LRESULT ANIMATE_Play(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
+
+    /* nothing opened */
+    if (!infoPtr->hMMio)
+       return FALSE;
+
+    if (infoPtr->hThread || infoPtr->uTimer) {
+       FIXME("Already playing ? what should I do ??\n");
+       ANIMATE_DoStop(infoPtr);
+    }
+
+    infoPtr->nFromFrame = (INT)LOWORD(lParam);
+    infoPtr->nToFrame   = (INT)HIWORD(lParam);
+    infoPtr->nLoop      = (INT)wParam;
+
+    if (infoPtr->nToFrame == 0xFFFF)
+       infoPtr->nToFrame = infoPtr->mah.dwTotalFrames - 1;
+
+    TRACE("(repeat=%d from=%d to=%d);\n",
+         infoPtr->nLoop, infoPtr->nFromFrame, infoPtr->nToFrame);
+
+    if (infoPtr->nFromFrame >= infoPtr->nToFrame ||
+       infoPtr->nToFrame >= infoPtr->mah.dwTotalFrames)
+       return FALSE;
+
+    infoPtr->currFrame = infoPtr->nFromFrame;
+
+    if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TIMER) {
+       TRACE("Using a timer\n");
+       /* create a timer to display AVI */
+       infoPtr->uTimer = SetTimer(hWnd, 1, infoPtr->mah.dwMicroSecPerFrame / 1000, NULL);
+    } else {
+        DWORD threadID;
+
+       TRACE("Using an animation thread\n");
+        infoPtr->hThread = CreateThread(0,0,ANIMATE_AnimationThread,(LPVOID)infoPtr, 0, &threadID);
+        if(!infoPtr->hThread)
+        {
+           ERR("Could not create animation thread!\n");
+           return FALSE;
+    }
+
+    }
+
+    ANIMATE_Notify(infoPtr, ACN_START);
+
+    return TRUE;
+}
+
+
+static BOOL ANIMATE_GetAviInfo(ANIMATE_INFO *infoPtr)
+{
+    MMCKINFO           ckMainRIFF;
+    MMCKINFO           mmckHead;
+    MMCKINFO           mmckList;
+    MMCKINFO           mmckInfo;
+    DWORD              numFrame;
+    DWORD              insize;
+
+    if (mmioDescend(infoPtr->hMMio, &ckMainRIFF, NULL, 0) != 0) {
+       WARN("Can't find 'RIFF' chunk\n");
+       return FALSE;
+    }
+
+    if ((ckMainRIFF.ckid != FOURCC_RIFF) ||
+       (ckMainRIFF.fccType != mmioFOURCC('A', 'V', 'I', ' '))) {
+       WARN("Can't find 'AVI ' chunk\n");
+       return FALSE;
+    }
+
+    mmckHead.fccType = mmioFOURCC('h', 'd', 'r', 'l');
+    if (mmioDescend(infoPtr->hMMio, &mmckHead, &ckMainRIFF, MMIO_FINDLIST) != 0) {
+       WARN("Can't find 'hdrl' list\n");
+       return FALSE;
+    }
+
+    mmckInfo.ckid = mmioFOURCC('a', 'v', 'i', 'h');
+    if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckHead, MMIO_FINDCHUNK) != 0) {
+       WARN("Can't find 'avih' chunk\n");
+       return FALSE;
+    }
+
+    mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->mah, sizeof(infoPtr->mah));
+
+    TRACE("mah.dwMicroSecPerFrame=%ld\n",      infoPtr->mah.dwMicroSecPerFrame);
+    TRACE("mah.dwMaxBytesPerSec=%ld\n",        infoPtr->mah.dwMaxBytesPerSec);
+    TRACE("mah.dwPaddingGranularity=%ld\n",    infoPtr->mah.dwPaddingGranularity);
+    TRACE("mah.dwFlags=%ld\n",                         infoPtr->mah.dwFlags);
+    TRACE("mah.dwTotalFrames=%ld\n",           infoPtr->mah.dwTotalFrames);
+    TRACE("mah.dwInitialFrames=%ld\n",                 infoPtr->mah.dwInitialFrames);
+    TRACE("mah.dwStreams=%ld\n",               infoPtr->mah.dwStreams);
+    TRACE("mah.dwSuggestedBufferSize=%ld\n",   infoPtr->mah.dwSuggestedBufferSize);
+    TRACE("mah.dwWidth=%ld\n",                         infoPtr->mah.dwWidth);
+    TRACE("mah.dwHeight=%ld\n",                infoPtr->mah.dwHeight);
+
+    mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
+
+    mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');
+    if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) {
+       WARN("Can't find 'strl' list\n");
+       return FALSE;
+    }
+
+    mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'h');
+    if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) {
+       WARN("Can't find 'strh' chunk\n");
+       return FALSE;
+    }
+
+    mmioRead(infoPtr->hMMio, (LPSTR)&infoPtr->ash, sizeof(infoPtr->ash));
+
+    TRACE("ash.fccType='%c%c%c%c'\n",          LOBYTE(LOWORD(infoPtr->ash.fccType)),
+                                               HIBYTE(LOWORD(infoPtr->ash.fccType)),
+                                               LOBYTE(HIWORD(infoPtr->ash.fccType)),
+                                               HIBYTE(HIWORD(infoPtr->ash.fccType)));
+    TRACE("ash.fccHandler='%c%c%c%c'\n",       LOBYTE(LOWORD(infoPtr->ash.fccHandler)),
+                                               HIBYTE(LOWORD(infoPtr->ash.fccHandler)),
+                                               LOBYTE(HIWORD(infoPtr->ash.fccHandler)),
+                                               HIBYTE(HIWORD(infoPtr->ash.fccHandler)));
+    TRACE("ash.dwFlags=%ld\n",                         infoPtr->ash.dwFlags);
+    TRACE("ash.wPriority=%d\n",                infoPtr->ash.wPriority);
+    TRACE("ash.wLanguage=%d\n",                infoPtr->ash.wLanguage);
+    TRACE("ash.dwInitialFrames=%ld\n",                 infoPtr->ash.dwInitialFrames);
+    TRACE("ash.dwScale=%ld\n",                         infoPtr->ash.dwScale);
+    TRACE("ash.dwRate=%ld\n",                  infoPtr->ash.dwRate);
+    TRACE("ash.dwStart=%ld\n",                         infoPtr->ash.dwStart);
+    TRACE("ash.dwLength=%ld\n",                infoPtr->ash.dwLength);
+    TRACE("ash.dwSuggestedBufferSize=%ld\n",   infoPtr->ash.dwSuggestedBufferSize);
+    TRACE("ash.dwQuality=%ld\n",               infoPtr->ash.dwQuality);
+    TRACE("ash.dwSampleSize=%ld\n",            infoPtr->ash.dwSampleSize);
+    TRACE("ash.rcFrame=(%d,%d,%d,%d)\n",       infoPtr->ash.rcFrame.top, infoPtr->ash.rcFrame.left,
+         infoPtr->ash.rcFrame.bottom, infoPtr->ash.rcFrame.right);
+
+    mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
+
+    mmckInfo.ckid = mmioFOURCC('s', 't', 'r', 'f');
+    if (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, MMIO_FINDCHUNK) != 0) {
+       WARN("Can't find 'strh' chunk\n");
+       return FALSE;
+    }
+
+    infoPtr->inbih = HeapAlloc(GetProcessHeap(), 0, mmckInfo.cksize);
+    if (!infoPtr->inbih) {
+       WARN("Can't alloc input BIH\n");
+       return FALSE;
+    }
+
+    mmioRead(infoPtr->hMMio, (LPSTR)infoPtr->inbih, mmckInfo.cksize);
+
+    TRACE("bih.biSize=%ld\n",          infoPtr->inbih->biSize);
+    TRACE("bih.biWidth=%ld\n",                 infoPtr->inbih->biWidth);
+    TRACE("bih.biHeight=%ld\n",        infoPtr->inbih->biHeight);
+    TRACE("bih.biPlanes=%d\n",                 infoPtr->inbih->biPlanes);
+    TRACE("bih.biBitCount=%d\n",       infoPtr->inbih->biBitCount);
+    TRACE("bih.biCompression=%ld\n",   infoPtr->inbih->biCompression);
+    TRACE("bih.biSizeImage=%ld\n",     infoPtr->inbih->biSizeImage);
+    TRACE("bih.biXPelsPerMeter=%ld\n",         infoPtr->inbih->biXPelsPerMeter);
+    TRACE("bih.biYPelsPerMeter=%ld\n",         infoPtr->inbih->biYPelsPerMeter);
+    TRACE("bih.biClrUsed=%ld\n",       infoPtr->inbih->biClrUsed);
+    TRACE("bih.biClrImportant=%ld\n",  infoPtr->inbih->biClrImportant);
+
+    mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
+
+    mmioAscend(infoPtr->hMMio, &mmckList, 0);
+
+#if 0
+    /* an AVI has 0 or 1 video stream, and to be animated should not contain
+     * an audio stream, so only one strl is allowed
+     */
+    mmckList.fccType = mmioFOURCC('s', 't', 'r', 'l');
+    if (mmioDescend(infoPtr->hMMio, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) {
+       WARN("There should be a single 'strl' list\n");
+       return FALSE;
+    }
+#endif
+
+    mmioAscend(infoPtr->hMMio, &mmckHead, 0);
+
+    /* no need to read optional JUNK chunk */
+
+    mmckList.fccType = mmioFOURCC('m', 'o', 'v', 'i');
+    if (mmioDescend(infoPtr->hMMio, &mmckList, &ckMainRIFF, MMIO_FINDLIST) != 0) {
+       WARN("Can't find 'movi' list\n");
+       return FALSE;
+    }
+
+    /* FIXME: should handle the 'rec ' LIST when present */
+
+    infoPtr->lpIndex = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                infoPtr->mah.dwTotalFrames * sizeof(DWORD));
+    if (!infoPtr->lpIndex) {
+       WARN("Can't alloc index array\n");
+       return FALSE;
+    }
+
+    numFrame = insize = 0;
+    while (mmioDescend(infoPtr->hMMio, &mmckInfo, &mmckList, 0) == 0 &&
+          numFrame < infoPtr->mah.dwTotalFrames) {
+       infoPtr->lpIndex[numFrame] = mmckInfo.dwDataOffset;
+       if (insize < mmckInfo.cksize)
+           insize = mmckInfo.cksize;
+       numFrame++;
+       mmioAscend(infoPtr->hMMio, &mmckInfo, 0);
+    }
+    if (numFrame != infoPtr->mah.dwTotalFrames) {
+       WARN("Found %ld frames (/%ld)\n", numFrame, infoPtr->mah.dwTotalFrames);
+       return FALSE;
+    }
+    if (insize > infoPtr->ash.dwSuggestedBufferSize) {
+       WARN("insize=%ld suggestedSize=%ld\n", insize, infoPtr->ash.dwSuggestedBufferSize);
+       infoPtr->ash.dwSuggestedBufferSize = insize;
+    }
+
+    infoPtr->indata = HeapAlloc(GetProcessHeap(), 0, infoPtr->ash.dwSuggestedBufferSize);
+    if (!infoPtr->indata) {
+       WARN("Can't alloc input buffer\n");
+       return FALSE;
+    }
+
+    return TRUE;
+}
+
+
+static BOOL    ANIMATE_GetAviCodec(ANIMATE_INFO *infoPtr)
+{
+    DWORD      outSize;
+
+    /* check uncompressed AVI */
+    if ((infoPtr->ash.fccHandler == mmioFOURCC('D', 'I', 'B', ' ')) ||
+       (infoPtr->ash.fccHandler == mmioFOURCC('R', 'L', 'E', ' ')) ||
+       (infoPtr->ash.fccHandler == mmioFOURCC(0, 0, 0, 0)))
+    {
+        infoPtr->hic = 0;
+       return TRUE;
+    }
+
+    /* try to get a decompressor for that type */
+    infoPtr->hic = fnIC.fnICOpen(ICTYPE_VIDEO, infoPtr->ash.fccHandler, ICMODE_DECOMPRESS);
+    if (!infoPtr->hic) {
+       WARN("Can't load codec for the file\n");
+       return FALSE;
+    }
+
+    outSize = fnIC.fnICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT,
+                           (DWORD)infoPtr->inbih, 0L);
+
+    infoPtr->outbih = HeapAlloc(GetProcessHeap(), 0, outSize);
+    if (!infoPtr->outbih) {
+       WARN("Can't alloc output BIH\n");
+       return FALSE;
+    }
+
+    if (fnIC.fnICSendMessage(infoPtr->hic, ICM_DECOMPRESS_GET_FORMAT,
+                     (DWORD)infoPtr->inbih, (DWORD)infoPtr->outbih) != outSize) {
+       WARN("Can't get output BIH\n");
+       return FALSE;
+    }
+
+    infoPtr->outdata = HeapAlloc(GetProcessHeap(), 0, infoPtr->outbih->biSizeImage);
+    if (!infoPtr->outdata) {
+       WARN("Can't alloc output buffer\n");
+       return FALSE;
+    }
+
+    if (fnIC.fnICSendMessage(infoPtr->hic, ICM_DECOMPRESS_BEGIN,
+                     (DWORD)infoPtr->inbih, (DWORD)infoPtr->outbih) != ICERR_OK) {
+       WARN("Can't begin decompression\n");
+       return FALSE;
+    }
+
+    return TRUE;
+}
+
+static LRESULT ANIMATE_OpenA(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
+    HINSTANCE hInstance = (HINSTANCE)wParam;
+
+    ANIMATE_Free(infoPtr);
+    infoPtr->hWnd = hWnd;
+
+    if (!lParam) {
+       TRACE("Closing avi!\n");
+        /* installer of thebat! v1.62 requires FALSE here */
+       return (infoPtr->hMMio != 0);
+    }
+
+    if (!hInstance)
+       hInstance = (HINSTANCE)GetWindowLongA(hWnd, GWL_HINSTANCE);
+
+    if (HIWORD(lParam)) {
+       TRACE("(\"%s\");\n", (LPSTR)lParam);
+
+       if (!ANIMATE_LoadResA(infoPtr, hInstance, (LPSTR)lParam)) {
+           TRACE("No AVI resource found!\n");
+           if (!ANIMATE_LoadFileA(infoPtr, (LPSTR)lParam)) {
+               WARN("No AVI file found!\n");
+               return FALSE;
+           }
+       }
+    } else {
+       TRACE("(%u);\n", (WORD)LOWORD(lParam));
+
+       if (!ANIMATE_LoadResA(infoPtr, hInstance,
+                             MAKEINTRESOURCEA((INT)lParam))) {
+           WARN("No AVI resource found!\n");
+           return FALSE;
+       }
+    }
+
+    if (!ANIMATE_GetAviInfo(infoPtr)) {
+       WARN("Can't get AVI information\n");
+       ANIMATE_Free(infoPtr);
+       return FALSE;
+    }
+
+    if (!ANIMATE_GetAviCodec(infoPtr)) {
+       WARN("Can't get AVI Codec\n");
+       ANIMATE_Free(infoPtr);
+       return FALSE;
+    }
+
+    if (!GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) {
+       SetWindowPos(hWnd, 0, 0, 0, infoPtr->mah.dwWidth, infoPtr->mah.dwHeight,
+                    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
+    }
+
+    if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_AUTOPLAY) {
+       return ANIMATE_Play(hWnd, -1, (LPARAM)MAKELONG(0, infoPtr->mah.dwTotalFrames-1));
+    }
+
+    return TRUE;
+}
+
+
+/* << ANIMATE_Open32W >> */
+
+static LRESULT ANIMATE_Stop(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
+
+    /* nothing opened */
+    if (!infoPtr->hMMio)
+       return FALSE;
+
+    ANIMATE_DoStop(infoPtr);
+    return TRUE;
+}
+
+
+static LRESULT ANIMATE_Create(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO*      infoPtr;
+
+    if (!fnIC.hModule) /* FIXME: not thread safe */
+    {
+       /* since there's a circular dep between msvfw32 and comctl32, we could either:
+        * - fix the build chain to allow this circular dep
+        * - handle it by hand
+        * AJ wants the latter :-(
+        */
+       fnIC.hModule = LoadLibraryA("msvfw32.dll");
+       if (!fnIC.hModule) return FALSE;
+
+       fnIC.fnICOpen        = (void*)GetProcAddress(fnIC.hModule, "ICOpen");
+       fnIC.fnICClose       = (void*)GetProcAddress(fnIC.hModule, "ICClose");
+       fnIC.fnICSendMessage = (void*)GetProcAddress(fnIC.hModule, "ICSendMessage");
+       fnIC.fnICDecompress  = (void*)GetProcAddress(fnIC.hModule, "ICDecompress");
+    }
+
+    /* allocate memory for info structure */
+    infoPtr = (ANIMATE_INFO *)Alloc(sizeof(ANIMATE_INFO));
+    if (!infoPtr) {
+       ERR("could not allocate info memory!\n");
+       return 0;
+    }
+
+    TRACE("Animate style=0x%08lx, parent=%08lx\n", GetWindowLongA(hWnd, GWL_STYLE), (DWORD)GetParent(hWnd));
+
+    /* store crossref hWnd <-> info structure */
+    SetWindowLongA(hWnd, 0, (DWORD)infoPtr);
+    infoPtr->hWnd = hWnd;
+    infoPtr->transparentColor = ANIMATE_COLOR_NONE;
+    infoPtr->hbmPrevFrame = 0;
+
+    InitializeCriticalSection(&infoPtr->cs);
+
+    return 0;
+}
+
+
+static LRESULT ANIMATE_Destroy(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    ANIMATE_INFO *infoPtr = ANIMATE_GetInfoPtr(hWnd);
+
+
+    /* free avi data */
+    ANIMATE_Free(infoPtr);
+
+    /* free animate info data */
+    Free(infoPtr);
+    SetWindowLongA(hWnd, 0, 0);
+
+    return 0;
+}
+
+
+static LRESULT ANIMATE_EraseBackground(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    RECT rect;
+    HBRUSH hBrush = 0;
+
+    if(GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)
+    {
+        hBrush = (HBRUSH)SendMessageA(GetParent(hWnd),WM_CTLCOLORSTATIC,
+                                     wParam, (LPARAM)hWnd);
+    }
+
+    GetClientRect(hWnd, &rect);
+    FillRect((HDC)wParam, &rect, hBrush ? hBrush : GetCurrentObject((HDC)wParam, OBJ_BRUSH));
+
+    return TRUE;
+}
+
+static LRESULT WINAPI ANIMATE_Size(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_CENTER) {
+       InvalidateRect(hWnd, NULL, TRUE);
+    }
+    return TRUE;
+}
+
+static LRESULT WINAPI ANIMATE_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);
+    if (!ANIMATE_GetInfoPtr(hWnd) && (uMsg != WM_NCCREATE))
+       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+    switch (uMsg)
+    {
+    case ACM_OPENA:
+       return ANIMATE_OpenA(hWnd, wParam, lParam);
+
+       /*      case ACM_OPEN32W: FIXME!! */
+       /*          return ANIMATE_Open32W(hWnd, wParam, lParam); */
+
+    case ACM_PLAY:
+       return ANIMATE_Play(hWnd, wParam, lParam);
+
+    case ACM_STOP:
+       return ANIMATE_Stop(hWnd, wParam, lParam);
+
+    case WM_NCCREATE:
+       ANIMATE_Create(hWnd, wParam, lParam);
+       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+
+    case WM_NCHITTEST:
+       return HTTRANSPARENT;
+
+    case WM_DESTROY:
+       ANIMATE_Destroy(hWnd, wParam, lParam);
+       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+
+    case WM_ERASEBKGND:
+       ANIMATE_EraseBackground(hWnd, wParam, lParam);
+       break;
+
+    /* case WM_STYLECHANGED: FIXME shall we do something ?? */
+
+    case WM_TIMER:
+       if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)
+        {
+            ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd);
+            infoPtr->hbrushBG = (HBRUSH)SendMessageA(GetParent(hWnd),
+                                                    WM_CTLCOLORSTATIC,
+                                                    wParam, (LPARAM)hWnd);
+        }
+       return ANIMATE_DrawFrame(ANIMATE_GetInfoPtr(hWnd));
+
+    case WM_CLOSE:
+       ANIMATE_Free(ANIMATE_GetInfoPtr(hWnd));
+       return TRUE;
+
+    case WM_PAINT:
+        {
+            ANIMATE_INFO* infoPtr = ANIMATE_GetInfoPtr(hWnd);
+
+            /* the animation isn't playing, don't paint */
+           if(!infoPtr->uTimer && !infoPtr->hThread)
+               /* default paint handling */
+               return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+
+            if (GetWindowLongA(hWnd, GWL_STYLE) & ACS_TRANSPARENT)
+                infoPtr->hbrushBG = (HBRUSH)SendMessageA(GetParent(hWnd),
+                                                        WM_CTLCOLORSTATIC,
+                                                        wParam, (LPARAM)hWnd);
+
+            if (wParam)
+            {
+                EnterCriticalSection(&infoPtr->cs);
+                ANIMATE_PaintFrame(infoPtr, (HDC)wParam);
+                LeaveCriticalSection(&infoPtr->cs);
+            }
+            else
+            {
+               PAINTSTRUCT ps;
+               HDC hDC = BeginPaint(hWnd, &ps);
+
+                EnterCriticalSection(&infoPtr->cs);
+                ANIMATE_PaintFrame(infoPtr, hDC);
+                LeaveCriticalSection(&infoPtr->cs);
+
+               EndPaint(hWnd, &ps);
+           }
+        }
+       break;
+
+    case WM_SIZE:
+       ANIMATE_Size(hWnd, wParam, lParam);
+       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+
+    default:
+       if ((uMsg >= WM_USER) && (uMsg < WM_APP))
+           ERR("unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam);
+
+       return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+    }
+    return 0;
+}
+
+void ANIMATE_Register(void)
+{
+    WNDCLASSA wndClass;
+
+    ZeroMemory(&wndClass, sizeof(WNDCLASSA));
+    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
+    wndClass.lpfnWndProc   = (WNDPROC)ANIMATE_WindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(ANIMATE_INFO *);
+    wndClass.hCursor       = LoadCursorA(0, (LPSTR)IDC_ARROW);
+    wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
+    wndClass.lpszClassName = ANIMATE_CLASSA;
+
+    RegisterClassA(&wndClass);
+}
+
+
+void ANIMATE_Unregister(void)
+{
+    UnregisterClassA(ANIMATE_CLASSA, NULL);
+}
index c4b7485..9c288f6 100644 (file)
-/*\r
- * ComboBoxEx control\r
- *\r
- * Copyright 1998, 1999 Eric Kohl\r
- * Copyright 2000, 2001, 2002 Guy Albertelli <galberte@neo.lrun.com>\r
- * Copyright 2002 Dimitrie O. Paun\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * NOTE\r
- * \r
- * This code was audited for completeness against the documented features\r
- * of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.\r
- * \r
- * Unless otherwise noted, we belive this code to be complete, as per\r
- * the specification mentioned above.\r
- * If you discover missing features, or bugs, please note them below.\r
- * \r
- */\r
-\r
-#include <stdarg.h>\r
-#include <string.h>\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "wingdi.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-#include "commctrl.h"\r
-#include "comctl32.h"\r
-#include "wine/debug.h"\r
-#include "wine/unicode.h"\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(comboex);\r
-\r
-/* Item structure */\r
-typedef struct\r
-{\r
-    VOID         *next;\r
-    UINT         mask;\r
-    LPWSTR       pszText;\r
-    LPWSTR       pszTemp;\r
-    int          cchTextMax;\r
-    int          iImage;\r
-    int          iSelectedImage;\r
-    int          iOverlay;\r
-    int          iIndent;\r
-    LPARAM       lParam;\r
-} CBE_ITEMDATA;\r
-\r
-/* ComboBoxEx structure */\r
-typedef struct\r
-{\r
-    HIMAGELIST   himl;\r
-    HWND         hwndSelf;         /* my own hwnd */\r
-    HWND         hwndCombo;\r
-    HWND         hwndEdit;\r
-    WNDPROC      prevEditWndProc;  /* previous Edit WNDPROC value */\r
-    WNDPROC      prevComboWndProc; /* previous Combo WNDPROC value */\r
-    DWORD        dwExtStyle;\r
-    INT          selected;         /* index of selected item */\r
-    DWORD        flags;            /* WINE internal flags */\r
-    HFONT        defaultFont;\r
-    HFONT        font;\r
-    INT          nb_items;         /* Number of items */\r
-    BOOL         unicode;          /* TRUE if this window is Unicode   */\r
-    BOOL         NtfUnicode;       /* TRUE if parent wants notify in Unicode */\r
-    CBE_ITEMDATA *edit;            /* item data for edit item */\r
-    CBE_ITEMDATA *items;           /* Array of items */\r
-} COMBOEX_INFO;\r
-\r
-/* internal flags in the COMBOEX_INFO structure */\r
-#define  WCBE_ACTEDIT          0x00000001  /* Edit active i.e.\r
-                                             * CBEN_BEGINEDIT issued\r
-                                             * but CBEN_ENDEDIT{A|W}\r
-                                             * not yet issued. */\r
-#define  WCBE_EDITCHG          0x00000002  /* Edit issued EN_CHANGE */\r
-#define  WCBE_EDITHASCHANGED   (WCBE_ACTEDIT | WCBE_EDITCHG)\r
-#define  WCBE_EDITFOCUSED      0x00000004  /* Edit control has focus */\r
-#define  WCBE_MOUSECAPTURED    0x00000008  /* Combo has captured mouse */\r
-#define  WCBE_MOUSEDRAGGED      0x00000010  /* User has dragged in combo */\r
-\r
-#define ID_CB_EDIT             1001\r
-\r
-\r
-/*\r
- * Special flag set in DRAWITEMSTRUCT itemState field. It is set by\r
- * the ComboEx version of the Combo Window Proc so that when the\r
- * WM_DRAWITEM message is then passed to ComboEx, we know that this\r
- * particular WM_DRAWITEM message is for listbox only items. Any messasges\r
- * without this flag is then for the Edit control field.\r
- *\r
- * We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that\r
- * only version 4.0 applications will have ODS_COMBOBOXEDIT set.\r
- */\r
-#define ODS_COMBOEXLBOX                0x4000\r
-\r
-\r
-\r
-/* Height in pixels of control over the amount of the selected font */\r
-#define CBE_EXTRA              3\r
-\r
-/* Indent amount per MS documentation */\r
-#define CBE_INDENT             10\r
-\r
-/* Offset in pixels from left side for start of image or text */\r
-#define CBE_STARTOFFSET                6\r
-\r
-/* Offset between image and text */\r
-#define CBE_SEP                        4\r
-\r
-#define COMBOEX_SUBCLASS_PROP  "CCComboEx32SubclassInfo"\r
-#define COMBOEX_GetInfoPtr(hwnd) ((COMBOEX_INFO *)GetWindowLongW (hwnd, 0))\r
-\r
-\r
-/* Things common to the entire DLL */\r
-static LRESULT WINAPI\r
-COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
-static LRESULT WINAPI\r
-COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
-static int CALLBACK\r
-COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code);\r
-static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr);\r
-typedef INT (WINAPI *cmp_func_t)(LPCWSTR, LPCWSTR);\r
-\r
-inline static BOOL is_textW(LPCWSTR str)\r
-{\r
-    return str && str != LPSTR_TEXTCALLBACKW;\r
-}\r
-\r
-inline static BOOL is_textA(LPCSTR str)\r
-{\r
-    return str && str != LPSTR_TEXTCALLBACKA;\r
-}\r
-\r
-inline static LPCSTR debugstr_txt(LPCWSTR str)\r
-{\r
-    if (str == LPSTR_TEXTCALLBACKW) return "(callback)";\r
-    return debugstr_w(str);\r
-}\r
-\r
-static void COMBOEX_DumpItem (CBE_ITEMDATA *item)\r
-{\r
-    TRACE("item %p - mask=%08x, pszText=%p, cchTM=%d, iImage=%d\n",\r
-          item, item->mask, item->pszText, item->cchTextMax, item->iImage);\r
-    TRACE("item %p - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",\r
-          item, item->iSelectedImage, item->iOverlay, item->iIndent, item->lParam);\r
-    if (item->mask & CBEIF_TEXT)\r
-        TRACE("item %p - pszText=%s\n", item, debugstr_txt(item->pszText));\r
-}\r
-\r
-\r
-static void COMBOEX_DumpInput (COMBOBOXEXITEMW *input)\r
-{\r
-    TRACE("input - mask=%08x, iItem=%d, pszText=%p, cchTM=%d, iImage=%d\n",\r
-          input->mask, input->iItem, input->pszText, input->cchTextMax,\r
-          input->iImage);\r
-    if (input->mask & CBEIF_TEXT)\r
-        TRACE("input - pszText=<%s>\n", debugstr_txt(input->pszText));\r
-    TRACE("input - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",\r
-          input->iSelectedImage, input->iOverlay, input->iIndent, input->lParam);\r
-}\r
-\r
-\r
-inline static CBE_ITEMDATA *get_item_data(COMBOEX_INFO *infoPtr, INT index)\r
-{\r
-    return (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, CB_GETITEMDATA,\r
-                                        (WPARAM)index, 0);\r
-}\r
-\r
-inline static cmp_func_t get_cmp_func(COMBOEX_INFO *infoPtr)\r
-{\r
-    return infoPtr->dwExtStyle & CBES_EX_CASESENSITIVE ? lstrcmpW : lstrcmpiW;\r
-}\r
-\r
-static INT COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr)\r
-{\r
-    hdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);\r
-    hdr->hwndFrom = infoPtr->hwndSelf;\r
-    hdr->code = code;\r
-    if (infoPtr->NtfUnicode)\r
-       return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,\r
-                            (LPARAM)hdr);\r
-    else\r
-       return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,\r
-                            (LPARAM)hdr);\r
-}\r
-\r
-\r
-static INT\r
-COMBOEX_NotifyItem (COMBOEX_INFO *infoPtr, INT code, NMCOMBOBOXEXW *hdr)\r
-{\r
-    /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */\r
-    if (infoPtr->NtfUnicode)\r
-       return COMBOEX_Notify (infoPtr, code, &hdr->hdr);\r
-    else {\r
-       LPWSTR wstr = hdr->ceItem.pszText;\r
-       LPSTR astr = 0;\r
-       INT ret, len = 0;\r
-\r
-       if ((hdr->ceItem.mask & CBEIF_TEXT) && is_textW(wstr)) {\r
-           len = WideCharToMultiByte (CP_ACP, 0, wstr, -1, 0, 0, NULL, NULL);\r
-           if (len > 0) {\r
-               astr = (LPSTR)Alloc ((len + 1)*sizeof(CHAR));\r
-               if (!astr) return 0;\r
-               WideCharToMultiByte (CP_ACP, 0, wstr, -1, astr, len, 0, 0);\r
-               hdr->ceItem.pszText = (LPWSTR)astr;\r
-           }\r
-       }\r
-\r
-       if (code == CBEN_ENDEDITW) code = CBEN_ENDEDITA;\r
-       else if (code == CBEN_GETDISPINFOW) code = CBEN_GETDISPINFOA;\r
-       else if (code == CBEN_DRAGBEGINW) code = CBEN_DRAGBEGINA;\r
-\r
-       ret = COMBOEX_Notify (infoPtr, code, (NMHDR *)hdr);\r
-\r
-       if (astr && hdr->ceItem.pszText == (LPWSTR)astr)\r
-           hdr->ceItem.pszText = wstr;\r
-\r
-       if (astr) Free(astr);\r
-\r
-       return ret;\r
-    }\r
-}\r
-\r
-\r
-static INT COMBOEX_NotifyEndEdit (COMBOEX_INFO *infoPtr, NMCBEENDEDITW *neew, LPCWSTR wstr)\r
-{\r
-    /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */\r
-    if (infoPtr->NtfUnicode) {\r
-       lstrcpynW(neew->szText, wstr, CBEMAXSTRLEN);\r
-       return COMBOEX_Notify (infoPtr, CBEN_ENDEDITW, &neew->hdr);\r
-    } else {\r
-       NMCBEENDEDITA neea;\r
-\r
-        memcpy (&neea.hdr, &neew->hdr, sizeof(NMHDR));\r
-        neea.fChanged = neew->fChanged;\r
-        neea.iNewSelection = neew->iNewSelection;\r
-        WideCharToMultiByte (CP_ACP, 0, wstr, -1, neea.szText, CBEMAXSTRLEN, 0, 0);\r
-        neea.iWhy = neew->iWhy;\r
-\r
-        return COMBOEX_Notify (infoPtr, CBEN_ENDEDITA, &neea.hdr);\r
-    }\r
-}\r
-\r
-\r
-static void COMBOEX_NotifyDragBegin(COMBOEX_INFO *infoPtr, LPCWSTR wstr)\r
-{\r
-    /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */\r
-    if (infoPtr->NtfUnicode) {\r
-        NMCBEDRAGBEGINW ndbw;\r
-\r
-       ndbw.iItemid = -1;\r
-       lstrcpynW(ndbw.szText, wstr, CBEMAXSTRLEN);\r
-       COMBOEX_Notify (infoPtr, CBEN_DRAGBEGINW, &ndbw.hdr);\r
-    } else {\r
-       NMCBEDRAGBEGINA ndba;\r
-\r
-       ndba.iItemid = -1;\r
-       WideCharToMultiByte (CP_ACP, 0, wstr, -1, ndba.szText, CBEMAXSTRLEN, 0, 0);\r
-\r
-       COMBOEX_Notify (infoPtr, CBEN_DRAGBEGINA, &ndba.hdr);\r
-    }\r
-}\r
-\r
-\r
-static void COMBOEX_FreeText (CBE_ITEMDATA *item)\r
-{\r
-    if (is_textW(item->pszText)) Free(item->pszText);\r
-    item->pszText = 0;\r
-    if (item->pszTemp) Free(item->pszTemp);\r
-    item->pszTemp = 0;\r
-}\r
-\r
-\r
-static LPCWSTR COMBOEX_GetText(COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)\r
-{\r
-    NMCOMBOBOXEXW nmce;\r
-    LPWSTR text, buf;\r
-    INT len;\r
-\r
-    if (item->pszText != LPSTR_TEXTCALLBACKW)\r
-       return item->pszText;\r
-\r
-    ZeroMemory(&nmce, sizeof(nmce));\r
-    nmce.ceItem.mask = CBEIF_TEXT;\r
-    nmce.ceItem.lParam = item->lParam;\r
-    COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);\r
-\r
-    if (is_textW(nmce.ceItem.pszText)) {\r
-       len = MultiByteToWideChar (CP_ACP, 0, (LPSTR)nmce.ceItem.pszText, -1, NULL, 0);\r
-       buf = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));\r
-       if (buf)\r
-           MultiByteToWideChar (CP_ACP, 0, (LPSTR)nmce.ceItem.pszText, -1, buf, len);\r
-       if (nmce.ceItem.mask & CBEIF_DI_SETITEM) {\r
-           COMBOEX_FreeText(item);\r
-           item->pszText = buf;\r
-       } else {\r
-           if (item->pszTemp) Free(item->pszTemp);\r
-           item->pszTemp = buf;\r
-       }\r
-       text = buf;\r
-    } else\r
-       text = nmce.ceItem.pszText;\r
-\r
-    if (nmce.ceItem.mask & CBEIF_DI_SETITEM)\r
-       item->pszText = text;\r
-    return text;\r
-}\r
-\r
-\r
-static void COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)\r
-{\r
-    HFONT nfont, ofont;\r
-    HDC mydc;\r
-\r
-    mydc = GetDC (0); /* why the entire screen???? */\r
-    nfont = (HFONT)SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);\r
-    ofont = (HFONT) SelectObject (mydc, nfont);\r
-    GetTextExtentPointA (mydc, "A", 1, size);\r
-    SelectObject (mydc, ofont);\r
-    ReleaseDC (0, mydc);\r
-    TRACE("selected font hwnd=%p, height=%ld\n", nfont, size->cy);\r
-}\r
-\r
-\r
-static void COMBOEX_CopyItem (CBE_ITEMDATA *item, COMBOBOXEXITEMW *cit)\r
-{\r
-    if (cit->mask & CBEIF_TEXT) {\r
-        /*\r
-         * when given a text buffer actually use that buffer\r
-         */\r
-        if (cit->pszText) {\r
-           if (is_textW(item->pszText))\r
-                lstrcpynW(cit->pszText, item->pszText, cit->cchTextMax);\r
-           else\r
-               cit->pszText[0] = 0;\r
-        } else {\r
-            cit->pszText        = item->pszText;\r
-            cit->cchTextMax     = item->cchTextMax;\r
-        }\r
-    }\r
-    if (cit->mask & CBEIF_IMAGE)\r
-       cit->iImage         = item->iImage;\r
-    if (cit->mask & CBEIF_SELECTEDIMAGE)\r
-       cit->iSelectedImage = item->iSelectedImage;\r
-    if (cit->mask & CBEIF_OVERLAY)\r
-       cit->iOverlay       = item->iOverlay;\r
-    if (cit->mask & CBEIF_INDENT)\r
-       cit->iIndent        = item->iIndent;\r
-    if (cit->mask & CBEIF_LPARAM)\r
-       cit->lParam         = item->lParam;\r
-}\r
-\r
-\r
-static void COMBOEX_AdjustEditPos (COMBOEX_INFO *infoPtr)\r
-{\r
-    SIZE mysize;\r
-    INT x, y, w, h, xioff;\r
-    RECT rect;\r
-\r
-    if (!infoPtr->hwndEdit) return;\r
-\r
-    if (infoPtr->himl && !(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGEINDENT)) {\r
-       IMAGEINFO iinfo;\r
-        iinfo.rcImage.left = iinfo.rcImage.right = 0;\r
-       ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo);\r
-       xioff = iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP;\r
-    }  else xioff = 0;\r
-\r
-    GetClientRect (infoPtr->hwndCombo, &rect);\r
-    InflateRect (&rect, -2, -2);\r
-    InvalidateRect (infoPtr->hwndCombo, &rect, TRUE);\r
-\r
-    /* reposition the Edit control based on whether icon exists */\r
-    COMBOEX_GetComboFontSize (infoPtr, &mysize);\r
-    TRACE("Combo font x=%ld, y=%ld\n", mysize.cx, mysize.cy);\r
-    x = xioff + CBE_STARTOFFSET + 1;\r
-    w = rect.right-rect.left - x - GetSystemMetrics(SM_CXVSCROLL) - 1;\r
-    h = mysize.cy + 1;\r
-    y = rect.bottom - h - 1;\r
-\r
-    TRACE("Combo client (%ld,%ld)-(%ld,%ld), setting Edit to (%d,%d)-(%d,%d)\n",\r
-         rect.left, rect.top, rect.right, rect.bottom, x, y, x + w, y + h);\r
-    SetWindowPos(infoPtr->hwndEdit, HWND_TOP, x, y, w, h,\r
-                SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);\r
-}\r
-\r
-\r
-static void COMBOEX_ReSize (COMBOEX_INFO *infoPtr)\r
-{\r
-    SIZE mysize;\r
-    UINT cy;\r
-    IMAGEINFO iinfo;\r
-\r
-    COMBOEX_GetComboFontSize (infoPtr, &mysize);\r
-    cy = mysize.cy + CBE_EXTRA;\r
-    if (infoPtr->himl && ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo)) {\r
-       cy = max (iinfo.rcImage.bottom - iinfo.rcImage.top, cy);\r
-       TRACE("upgraded height due to image:  height=%d\n", cy);\r
-    }\r
-    SendMessageW (infoPtr->hwndSelf, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)cy);\r
-    if (infoPtr->hwndCombo) {\r
-        SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,\r
-                     (WPARAM) 0, (LPARAM) cy);\r
-       if ( !(infoPtr->flags & CBES_EX_NOSIZELIMIT)) {\r
-           RECT comboRect;\r
-           if (GetWindowRect(infoPtr->hwndCombo, &comboRect)) {\r
-               RECT ourRect;\r
-               if (GetWindowRect(infoPtr->hwndSelf, &ourRect)) {\r
-                   if (comboRect.bottom > ourRect.bottom) {\r
-                       POINT pt = { ourRect.left, ourRect.top };\r
-                       if (ScreenToClient(infoPtr->hwndSelf, &pt))\r
-                           MoveWindow( infoPtr->hwndSelf, pt.x, pt.y, ourRect.right - ourRect.left,\r
-                                       comboRect.bottom - comboRect.top, FALSE);\r
-                   }\r
-               }\r
-           }\r
-       }\r
-    }\r
-}\r
-\r
-\r
-static void COMBOEX_SetEditText (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)\r
-{\r
-    if (!infoPtr->hwndEdit) return;\r
-    /* native issues the following messages to the {Edit} control */\r
-    /*      WM_SETTEXT (0,addr)     */\r
-    /*      EM_SETSEL32 (0,0)       */\r
-    /*      EM_SETSEL32 (0,-1)      */\r
-    if (item->mask & CBEIF_TEXT) {\r
-       SendMessageW (infoPtr->hwndEdit, WM_SETTEXT, 0, (LPARAM)COMBOEX_GetText(infoPtr, item));\r
-       SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);\r
-       SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);\r
-    }\r
-}\r
-\r
-\r
-static CBE_ITEMDATA * COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index)\r
-{\r
-    CBE_ITEMDATA *item;\r
-    INT i;\r
-\r
-    if ((index > infoPtr->nb_items) || (index < -1))\r
-       return 0;\r
-    if (index == -1)\r
-       return infoPtr->edit;\r
-    item = infoPtr->items;\r
-    i = infoPtr->nb_items - 1;\r
-\r
-    /* find the item in the list */\r
-    while (item && (i > index)) {\r
-       item = (CBE_ITEMDATA *)item->next;\r
-       i--;\r
-    }\r
-    if (!item || (i != index)) {\r
-       ERR("COMBOBOXEX item structures broken. Please report!\n");\r
-       return 0;\r
-    }\r
-    return item;\r
-}\r
-\r
-\r
-static inline BOOL COMBOEX_HasEdit(COMBOEX_INFO *infoPtr)\r
-{\r
-    return infoPtr->hwndEdit ? TRUE : FALSE;\r
-}\r
-\r
-\r
-/* ***  CBEM_xxx message support  *** */\r
-\r
-\r
-static INT COMBOEX_DeleteItem (COMBOEX_INFO *infoPtr, INT index)\r
-{\r
-    CBE_ITEMDATA *item;\r
-\r
-    TRACE("(index=%d)\n", index);\r
-\r
-    /* if item number requested does not exist then return failure */\r
-    if ((index > infoPtr->nb_items) || (index < 0)) return CB_ERR;\r
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) return CB_ERR;\r
-\r
-    /* doing this will result in WM_DELETEITEM being issued */\r
-    SendMessageW (infoPtr->hwndCombo, CB_DELETESTRING, (WPARAM)index, 0);\r
-\r
-    return infoPtr->nb_items;\r
-}\r
-\r
-\r
-static BOOL COMBOEX_GetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)\r
-{\r
-    INT index = cit->iItem;\r
-    CBE_ITEMDATA *item;\r
-\r
-    TRACE("(...)\n");\r
-\r
-    /* if item number requested does not exist then return failure */\r
-    if ((index > infoPtr->nb_items) || (index < -1)) return FALSE;\r
-\r
-    /* if the item is the edit control and there is no edit control, skip */\r
-    if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;\r
-\r
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;\r
-\r
-    COMBOEX_CopyItem (item, cit);\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static BOOL COMBOEX_GetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)\r
-{\r
-    COMBOBOXEXITEMW tmpcit;\r
-\r
-    TRACE("(...)\n");\r
-\r
-    tmpcit.mask = cit->mask;\r
-    tmpcit.iItem = cit->iItem;\r
-    tmpcit.pszText = 0;\r
-    if(!COMBOEX_GetItemW (infoPtr, &tmpcit)) return FALSE;\r
-\r
-    if (is_textW(tmpcit.pszText) && cit->pszText)\r
-        WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1,\r
-                            cit->pszText, cit->cchTextMax, NULL, NULL);\r
-    else if (cit->pszText) cit->pszText[0] = 0;\r
-    else cit->pszText = (LPSTR)tmpcit.pszText;\r
-\r
-    cit->iImage = tmpcit.iImage;\r
-    cit->iSelectedImage = tmpcit.iSelectedImage;\r
-    cit->iOverlay = tmpcit.iOverlay;\r
-    cit->iIndent = tmpcit.iIndent;\r
-    cit->lParam = tmpcit.lParam;\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-inline static BOOL COMBOEX_HasEditChanged (COMBOEX_INFO *infoPtr)\r
-{\r
-    return COMBOEX_HasEdit(infoPtr) &&\r
-          (infoPtr->flags & WCBE_EDITHASCHANGED) == WCBE_EDITHASCHANGED;\r
-}\r
-\r
-\r
-static INT COMBOEX_InsertItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)\r
-{\r
-    INT index;\r
-    CBE_ITEMDATA *item;\r
-    NMCOMBOBOXEXW nmcit;\r
-\r
-    TRACE("\n");\r
-\r
-    if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);\r
-\r
-    /* get real index of item to insert */\r
-    index = cit->iItem;\r
-    if (index == -1) index = infoPtr->nb_items;\r
-    if (index > infoPtr->nb_items) index = infoPtr->nb_items;\r
-\r
-    /* get zero-filled space and chain it in */\r
-    if(!(item = (CBE_ITEMDATA *)Alloc (sizeof(*item)))) return -1;\r
-\r
-    /* locate position to insert new item in */\r
-    if (index == infoPtr->nb_items) {\r
-        /* fast path for iItem = -1 */\r
-        item->next = infoPtr->items;\r
-       infoPtr->items = item;\r
-    }\r
-    else {\r
-        INT i = infoPtr->nb_items-1;\r
-       CBE_ITEMDATA *moving = infoPtr->items;\r
-\r
-       while ((i > index) && moving) {\r
-           moving = (CBE_ITEMDATA *)moving->next;\r
-           i--;\r
-       }\r
-       if (!moving) {\r
-           ERR("COMBOBOXEX item structures broken. Please report!\n");\r
-           Free(item);\r
-           return -1;\r
-       }\r
-       item->next = moving->next;\r
-       moving->next = item;\r
-    }\r
-\r
-    /* fill in our hidden item structure */\r
-    item->mask = cit->mask;\r
-    if (item->mask & CBEIF_TEXT) {\r
-       INT len = 0;\r
-\r
-        if (is_textW(cit->pszText)) len = strlenW (cit->pszText);\r
-       if (len > 0) {\r
-           item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));\r
-           if (!item->pszText) {\r
-               Free(item);\r
-               return -1;\r
-           }\r
-           strcpyW (item->pszText, cit->pszText);\r
-       }\r
-       else if (cit->pszText == LPSTR_TEXTCALLBACKW)\r
-           item->pszText = LPSTR_TEXTCALLBACKW;\r
-        item->cchTextMax = cit->cchTextMax;\r
-    }\r
-    if (item->mask & CBEIF_IMAGE)\r
-        item->iImage = cit->iImage;\r
-    if (item->mask & CBEIF_SELECTEDIMAGE)\r
-        item->iSelectedImage = cit->iSelectedImage;\r
-    if (item->mask & CBEIF_OVERLAY)\r
-        item->iOverlay = cit->iOverlay;\r
-    if (item->mask & CBEIF_INDENT)\r
-        item->iIndent = cit->iIndent;\r
-    if (item->mask & CBEIF_LPARAM)\r
-        item->lParam = cit->lParam;\r
-    infoPtr->nb_items++;\r
-\r
-    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);\r
-\r
-    SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING,\r
-                 (WPARAM)cit->iItem, (LPARAM)item);\r
-\r
-    memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));\r
-    COMBOEX_CopyItem (item, &nmcit.ceItem);\r
-    COMBOEX_NotifyItem (infoPtr, CBEN_INSERTITEM, &nmcit);\r
-\r
-    return index;\r
-\r
-}\r
-\r
-\r
-static INT COMBOEX_InsertItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)\r
-{\r
-    COMBOBOXEXITEMW citW;\r
-    LPWSTR wstr = NULL;\r
-    INT        ret;\r
-\r
-    memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA));\r
-    if (cit->mask & CBEIF_TEXT && is_textA(cit->pszText)) {\r
-       INT len = MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, NULL, 0);\r
-       wstr = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));\r
-       if (!wstr) return -1;\r
-       MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, wstr, len);\r
-       citW.pszText = wstr;\r
-    }\r
-    ret = COMBOEX_InsertItemW(infoPtr, &citW);\r
-\r
-    if (wstr) Free(wstr);\r
-\r
-    return ret;\r
-}\r
-\r
-\r
-static DWORD\r
-COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style)\r
-{\r
-    DWORD dwTemp;\r
-\r
-    TRACE("(mask=x%08lx, style=0x%08lx)\n", mask, style);\r
-\r
-    dwTemp = infoPtr->dwExtStyle;\r
-\r
-    if (mask)\r
-       infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~mask) | style;\r
-    else\r
-       infoPtr->dwExtStyle = style;\r
-\r
-    /* see if we need to change the word break proc on the edit */\r
-    if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC) {\r
-       SendMessageW(infoPtr->hwndEdit, EM_SETWORDBREAKPROC, 0,\r
-                    (infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ?\r
-                        (LPARAM)COMBOEX_PathWordBreakProc : 0);\r
-    }\r
-\r
-    /* test if the control's appearance has changed */\r
-    mask = CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT;\r
-    if ((infoPtr->dwExtStyle & mask) != (dwTemp & mask)) {\r
-       /* if state of EX_NOEDITIMAGE changes, invalidate all */\r
-       TRACE("EX_NOEDITIMAGE state changed to %ld\n",\r
-             infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE);\r
-       InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);\r
-       COMBOEX_AdjustEditPos (infoPtr);\r
-       if (infoPtr->hwndEdit)\r
-           InvalidateRect (infoPtr->hwndEdit, NULL, TRUE);\r
-    }\r
-\r
-    return dwTemp;\r
-}\r
-\r
-\r
-static HIMAGELIST COMBOEX_SetImageList (COMBOEX_INFO *infoPtr, HIMAGELIST himl)\r
-{\r
-    HIMAGELIST himlTemp = infoPtr->himl;\r
-\r
-    TRACE("(...)\n");\r
-\r
-    infoPtr->himl = himl;\r
-\r
-    COMBOEX_ReSize (infoPtr);\r
-    InvalidateRect (infoPtr->hwndCombo, NULL, TRUE);\r
-\r
-    /* reposition the Edit control based on whether icon exists */\r
-    COMBOEX_AdjustEditPos (infoPtr);\r
-    return himlTemp;\r
-}\r
-\r
-static BOOL COMBOEX_SetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)\r
-{\r
-    INT index = cit->iItem;\r
-    CBE_ITEMDATA *item;\r
-\r
-    if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);\r
-\r
-    /* if item number requested does not exist then return failure */\r
-    if ((index > infoPtr->nb_items) || (index < -1)) return FALSE;\r
-\r
-    /* if the item is the edit control and there is no edit control, skip */\r
-    if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;\r
-\r
-    if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;\r
-\r
-    /* add/change stuff to the internal item structure */\r
-    item->mask |= cit->mask;\r
-    if (cit->mask & CBEIF_TEXT) {\r
-       INT len = 0;\r
-\r
-       COMBOEX_FreeText(item);\r
-        if (is_textW(cit->pszText)) len = strlenW(cit->pszText);\r
-       if (len > 0) {\r
-           item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));\r
-           if (!item->pszText) return FALSE;\r
-           strcpyW(item->pszText, cit->pszText);\r
-       } else if (cit->pszText == LPSTR_TEXTCALLBACKW)\r
-           item->pszText = LPSTR_TEXTCALLBACKW;\r
-        item->cchTextMax = cit->cchTextMax;\r
-    }\r
-    if (cit->mask & CBEIF_IMAGE)\r
-        item->iImage = cit->iImage;\r
-    if (cit->mask & CBEIF_SELECTEDIMAGE)\r
-        item->iSelectedImage = cit->iSelectedImage;\r
-    if (cit->mask & CBEIF_OVERLAY)\r
-        item->iOverlay = cit->iOverlay;\r
-    if (cit->mask & CBEIF_INDENT)\r
-        item->iIndent = cit->iIndent;\r
-    if (cit->mask & CBEIF_LPARAM)\r
-        cit->lParam = cit->lParam;\r
-\r
-    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);\r
-\r
-    /* if original request was to update edit control, do some fast foot work */\r
-    if (cit->iItem == -1) {\r
-       COMBOEX_SetEditText (infoPtr, item);\r
-       RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | RDW_INVALIDATE);\r
-    }\r
-    return TRUE;\r
-}\r
-\r
-static BOOL COMBOEX_SetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)\r
-{\r
-    COMBOBOXEXITEMW citW;\r
-    LPWSTR wstr = NULL;\r
-    BOOL ret;\r
-\r
-    memcpy(&citW, cit, sizeof(COMBOBOXEXITEMA));\r
-    if ((cit->mask & CBEIF_TEXT) && is_textA(cit->pszText)) {\r
-       INT len = MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, NULL, 0);\r
-       wstr = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));\r
-       if (!wstr) return FALSE;\r
-       MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, wstr, len);\r
-       citW.pszText = wstr;\r
-    }\r
-    ret = COMBOEX_SetItemW(infoPtr, &citW);\r
-\r
-    if (wstr) Free(wstr);\r
-\r
-    return ret;\r
-}\r
-\r
-\r
-static BOOL COMBOEX_SetUnicodeFormat (COMBOEX_INFO *infoPtr, BOOL value)\r
-{\r
-    BOOL bTemp = infoPtr->unicode;\r
-\r
-    TRACE("to %s, was %s\n", value ? "TRUE":"FALSE", bTemp ? "TRUE":"FALSE");\r
-\r
-    infoPtr->unicode = value;\r
-\r
-    return bTemp;\r
-}\r
-\r
-\r
-/* ***  CB_xxx message support  *** */\r
-\r
-static INT\r
-COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, INT start, LPCWSTR str)\r
-{\r
-    INT i;\r
-    cmp_func_t cmptext = get_cmp_func(infoPtr);\r
-    INT count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0);\r
-\r
-    /* now search from after starting loc and wrapping back to start */\r
-    for(i=start+1; i<count; i++) {\r
-       CBE_ITEMDATA *item = get_item_data(infoPtr, i);\r
-       if (cmptext(COMBOEX_GetText(infoPtr, item), str) == 0) return i;\r
-    }\r
-    for(i=0; i<=start; i++) {\r
-       CBE_ITEMDATA *item = get_item_data(infoPtr, i);\r
-       if (cmptext(COMBOEX_GetText(infoPtr, item), str) == 0) return i;\r
-    }\r
-    return CB_ERR;\r
-}\r
-\r
-\r
-static DWORD COMBOEX_GetItemData (COMBOEX_INFO *infoPtr, INT index)\r
-{\r
-    CBE_ITEMDATA *item1, *item2;\r
-    DWORD ret = 0;\r
-\r
-    item1 = get_item_data(infoPtr, index);\r
-    if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) {\r
-       item2 = COMBOEX_FindItem (infoPtr, index);\r
-       if (item2 != item1) {\r
-           ERR("data structures damaged!\n");\r
-           return CB_ERR;\r
-       }\r
-       if (item1->mask & CBEIF_LPARAM) ret = item1->lParam;\r
-       TRACE("returning 0x%08lx\n", ret);\r
-    } else {\r
-        ret = (DWORD)item1;\r
-        TRACE("non-valid result from combo, returning 0x%08lx\n", ret);\r
-    }\r
-    return ret;\r
-}\r
-\r
-\r
-static INT COMBOEX_SetCursel (COMBOEX_INFO *infoPtr, INT index)\r
-{\r
-    CBE_ITEMDATA *item;\r
-    INT sel;\r
-\r
-    if (!(item = COMBOEX_FindItem(infoPtr, index)))\r
-       return SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, index, 0);\r
-\r
-    TRACE("selecting item %d text=%s\n", index, debugstr_txt(item->pszText));\r
-    infoPtr->selected = index;\r
-\r
-    sel = (INT)SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, index, 0);\r
-    COMBOEX_SetEditText (infoPtr, item);\r
-    return sel;\r
-}\r
-\r
-\r
-static DWORD COMBOEX_SetItemData (COMBOEX_INFO *infoPtr, INT index, DWORD data)\r
-{\r
-    CBE_ITEMDATA *item1, *item2;\r
-\r
-    item1 = get_item_data(infoPtr, index);\r
-    if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) {\r
-       item2 = COMBOEX_FindItem (infoPtr, index);\r
-       if (item2 != item1) {\r
-           ERR("data structures damaged!\n");\r
-           return CB_ERR;\r
-       }\r
-       item1->mask |= CBEIF_LPARAM;\r
-       item1->lParam = data;\r
-       TRACE("setting lparam to 0x%08lx\n", data);\r
-       return 0;\r
-    }\r
-    TRACE("non-valid result from combo 0x%08lx\n", (DWORD)item1);\r
-    return (LRESULT)item1;\r
-}\r
-\r
-\r
-static INT COMBOEX_SetItemHeight (COMBOEX_INFO *infoPtr, INT index, UINT height)\r
-{\r
-    RECT cb_wrect, cbx_wrect, cbx_crect;\r
-\r
-    /* First, lets forward the message to the normal combo control\r
-       just like Windows.     */\r
-    if (infoPtr->hwndCombo)\r
-       if (SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,\r
-                        index, height) == CB_ERR) return CB_ERR;\r
-\r
-    GetWindowRect (infoPtr->hwndCombo, &cb_wrect);\r
-    GetWindowRect (infoPtr->hwndSelf, &cbx_wrect);\r
-    GetClientRect (infoPtr->hwndSelf, &cbx_crect);\r
-    /* the height of comboex as height of the combo + comboex border */\r
-    height = cb_wrect.bottom-cb_wrect.top\r
-             + cbx_wrect.bottom-cbx_wrect.top\r
-             - (cbx_crect.bottom-cbx_crect.top);\r
-    TRACE("EX window=(%ld,%ld)-(%ld,%ld), client=(%ld,%ld)-(%ld,%ld)\n",\r
-         cbx_wrect.left, cbx_wrect.top, cbx_wrect.right, cbx_wrect.bottom,\r
-         cbx_crect.left, cbx_crect.top, cbx_crect.right, cbx_crect.bottom);\r
-    TRACE("CB window=(%ld,%ld)-(%ld,%ld), EX setting=(0,0)-(%ld,%d)\n",\r
-         cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom,\r
-         cbx_wrect.right-cbx_wrect.left, height);\r
-    SetWindowPos (infoPtr->hwndSelf, HWND_TOP, 0, 0,\r
-                 cbx_wrect.right-cbx_wrect.left, height,\r
-                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-/* ***  WM_xxx message support  *** */\r
-\r
-\r
-static LRESULT COMBOEX_Create (HWND hwnd, LPCREATESTRUCTA cs)\r
-{\r
-    WCHAR COMBOBOX[] = { 'C', 'o', 'm', 'b', 'o', 'B', 'o', 'x', 0 };\r
-    WCHAR EDIT[] = { 'E', 'D', 'I', 'T', 0 };\r
-    WCHAR NIL[] = { 0 };\r
-    COMBOEX_INFO *infoPtr;\r
-    LOGFONTW mylogfont;\r
-    RECT wnrc1, clrc1, cmbwrc;\r
-    INT i;\r
-\r
-    /* allocate memory for info structure */\r
-    infoPtr = (COMBOEX_INFO *)Alloc (sizeof(COMBOEX_INFO));\r
-    if (!infoPtr) return -1;\r
-\r
-    /* initialize info structure */\r
-    /* note that infoPtr is allocated zero-filled */\r
-\r
-    infoPtr->hwndSelf = hwnd;\r
-    infoPtr->selected = -1;\r
-\r
-    infoPtr->unicode = IsWindowUnicode (hwnd);\r
-\r
-    i = SendMessageW(GetParent (hwnd), WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);\r
-    if ((i != NFR_ANSI) && (i != NFR_UNICODE)) {\r
-       WARN("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", i);\r
-       i = NFR_ANSI;\r
-    }\r
-    infoPtr->NtfUnicode = (i == NFR_UNICODE);\r
-\r
-    SetWindowLongW (hwnd, 0, (DWORD)infoPtr);\r
-\r
-    /* create combo box */\r
-    GetWindowRect(hwnd, &wnrc1);\r
-    GetClientRect(hwnd, &clrc1);\r
-    TRACE("EX window=(%ld,%ld)-(%ld,%ld) client=(%ld,%ld)-(%ld,%ld)\n",\r
-         wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom,\r
-         clrc1.left, clrc1.top, clrc1.right, clrc1.bottom);\r
-\r
-    /* Native version of ComboEx creates the ComboBox with DROPDOWNLIST */\r
-    /* specified. It then creates it's own version of the EDIT control  */\r
-    /* and makes the ComboBox the parent. This is because a normal      */\r
-    /* DROPDOWNLIST does not have a EDIT control, but we need one.      */\r
-    /* We also need to place the edit control at the proper location    */\r
-    /* (allow space for the icons).                                     */\r
-\r
-    infoPtr->hwndCombo = CreateWindowW (COMBOBOX, NIL,\r
-                        /* following line added to match native */\r
-                         WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL |\r
-                         CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST |\r
-                        /* was base and is necessary */\r
-                        WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED |\r
-                        GetWindowLongW (hwnd, GWL_STYLE),\r
-                        cs->y, cs->x, cs->cx, cs->cy, hwnd,\r
-                        (HMENU) GetWindowLongW (hwnd, GWL_ID),\r
-                        (HINSTANCE)GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);\r
-\r
-    /*\r
-     * native does the following at this point according to trace:\r
-     *  GetWindowThreadProcessId(hwndCombo,0)\r
-     *  GetCurrentThreadId()\r
-     *  GetWindowThreadProcessId(hwndCombo, &???)\r
-     *  GetCurrentProcessId()\r
-     */\r
-\r
-    /*\r
-     * Setup a property to hold the pointer to the COMBOBOXEX\r
-     * data structure.\r
-     */\r
-    SetPropA(infoPtr->hwndCombo, COMBOEX_SUBCLASS_PROP, hwnd);\r
-    infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndCombo,\r
-                               GWL_WNDPROC, (LONG)COMBOEX_ComboWndProc);\r
-    infoPtr->font = (HFONT)SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);\r
-\r
-\r
-    /*\r
-     * Now create our own EDIT control so we can position it.\r
-     * It is created only for CBS_DROPDOWN style\r
-     */\r
-    if ((cs->style & CBS_DROPDOWNLIST) == CBS_DROPDOWN) {\r
-       infoPtr->hwndEdit = CreateWindowExW (0, EDIT, NIL,\r
-                   WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_AUTOHSCROLL,\r
-                   0, 0, 0, 0,  /* will set later */\r
-                   infoPtr->hwndCombo,\r
-                   (HMENU) GetWindowLongW (hwnd, GWL_ID),\r
-                   (HINSTANCE)GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);\r
-\r
-       /* native does the following at this point according to trace:\r
-        *  GetWindowThreadProcessId(hwndEdit,0)\r
-        *  GetCurrentThreadId()\r
-        *  GetWindowThreadProcessId(hwndEdit, &???)\r
-        *  GetCurrentProcessId()\r
-        */\r
-\r
-       /*\r
-        * Setup a property to hold the pointer to the COMBOBOXEX\r
-        * data structure.\r
-        */\r
-        SetPropA(infoPtr->hwndEdit, COMBOEX_SUBCLASS_PROP, hwnd);\r
-       infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndEdit,\r
-                                GWL_WNDPROC, (LONG)COMBOEX_EditWndProc);\r
-       infoPtr->font = (HFONT)SendMessageW(infoPtr->hwndCombo, WM_GETFONT, 0, 0);\r
-    }\r
-\r
-    /*\r
-     * Locate the default font if necessary and then set it in\r
-     * all associated controls\r
-     */\r
-    if (!infoPtr->font) {\r
-       SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof(mylogfont),\r
-                              &mylogfont, 0);\r
-       infoPtr->font = infoPtr->defaultFont = CreateFontIndirectW (&mylogfont);\r
-    }\r
-    SendMessageW (infoPtr->hwndCombo, WM_SETFONT, (WPARAM)infoPtr->font, 0);\r
-    if (infoPtr->hwndEdit) {\r
-       SendMessageW (infoPtr->hwndEdit, WM_SETFONT, (WPARAM)infoPtr->font, 0);\r
-       SendMessageW (infoPtr->hwndEdit, EM_SETMARGINS, (WPARAM)EC_USEFONTINFO, 0);\r
-    }\r
-\r
-    COMBOEX_ReSize (infoPtr);\r
-\r
-    /* Above is fairly certain, below is much less certain. */\r
-\r
-    GetWindowRect(hwnd, &wnrc1);\r
-    GetClientRect(hwnd, &clrc1);\r
-    GetWindowRect(infoPtr->hwndCombo, &cmbwrc);\r
-    TRACE("EX window=(%ld,%ld)-(%ld,%ld) client=(%ld,%ld)-(%ld,%ld) CB wnd=(%ld,%ld)-(%ld,%ld)\n",\r
-         wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom,\r
-         clrc1.left, clrc1.top, clrc1.right, clrc1.bottom,\r
-         cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom);\r
-    SetWindowPos(infoPtr->hwndCombo, HWND_TOP,\r
-                0, 0, wnrc1.right-wnrc1.left, wnrc1.bottom-wnrc1.top,\r
-                SWP_NOACTIVATE | SWP_NOREDRAW);\r
-\r
-    GetWindowRect(infoPtr->hwndCombo, &cmbwrc);\r
-    TRACE("CB window=(%ld,%ld)-(%ld,%ld)\n",\r
-         cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom);\r
-    SetWindowPos(hwnd, HWND_TOP,\r
-                0, 0, cmbwrc.right-cmbwrc.left, cmbwrc.bottom-cmbwrc.top,\r
-                SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);\r
-\r
-    COMBOEX_AdjustEditPos (infoPtr);\r
-\r
-    /*\r
-     * Create an item structure to represent the data in the\r
-     * EDIT control. It is allocated zero-filled.\r
-     */\r
-    infoPtr->edit = (CBE_ITEMDATA *)Alloc (sizeof (CBE_ITEMDATA));\r
-    if (!infoPtr->edit) {\r
-       COMBOEX_Destroy(infoPtr);\r
-       return -1;\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_Command (COMBOEX_INFO *infoPtr, WPARAM wParam, LPARAM lParam)\r
-{\r
-    LRESULT lret;\r
-    INT command = HIWORD(wParam);\r
-    CBE_ITEMDATA *item = 0;\r
-    WCHAR wintext[520];\r
-    INT cursel, n, oldItem;\r
-    NMCBEENDEDITW cbeend;\r
-    DWORD oldflags;\r
-    HWND parent = GetParent (infoPtr->hwndSelf);\r
-\r
-    TRACE("for command %d\n", command);\r
-\r
-    switch (command)\r
-    {\r
-    case CBN_DROPDOWN:\r
-       SetFocus (infoPtr->hwndCombo);\r
-       ShowWindow (infoPtr->hwndEdit, SW_HIDE);\r
-       return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);\r
-\r
-    case CBN_CLOSEUP:\r
-       SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);\r
-       /*\r
-        * from native trace of first dropdown after typing in URL in IE4\r
-        *  CB_GETCURSEL(Combo)\r
-        *  GetWindowText(Edit)\r
-        *  CB_GETCURSEL(Combo)\r
-        *  CB_GETCOUNT(Combo)\r
-        *  CB_GETITEMDATA(Combo, n)\r
-        *  WM_NOTIFY(parent, CBEN_ENDEDITA|W)\r
-        *  CB_GETCURSEL(Combo)\r
-        *  CB_SETCURSEL(COMBOEX, n)\r
-        *  SetFocus(Combo)\r
-        * the rest is supposition\r
-        */\r
-       ShowWindow (infoPtr->hwndEdit, SW_SHOW);\r
-       InvalidateRect (infoPtr->hwndCombo, 0, TRUE);\r
-       InvalidateRect (infoPtr->hwndEdit, 0, TRUE);\r
-       cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);\r
-       if (cursel == -1) {\r
-            cmp_func_t cmptext = get_cmp_func(infoPtr);\r
-           /* find match from edit against those in Combobox */\r
-           GetWindowTextW (infoPtr->hwndEdit, wintext, 520);\r
-           n = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0);\r
-           for (cursel = 0; cursel < n; cursel++){\r
-                item = get_item_data(infoPtr, cursel);\r
-               if ((INT)item == CB_ERR) break;\r
-               if (!cmptext(COMBOEX_GetText(infoPtr, item), wintext)) break;\r
-           }\r
-           if ((cursel == n) || ((INT)item == CB_ERR)) {\r
-               TRACE("failed to find match??? item=%p cursel=%d\n",\r
-                     item, cursel);\r
-               if (infoPtr->hwndEdit)\r
-                   SetFocus(infoPtr->hwndEdit);\r
-               return 0;\r
-           }\r
-       }\r
-       else {\r
-            item = get_item_data(infoPtr, cursel);\r
-           if ((INT)item == CB_ERR) {\r
-               TRACE("failed to find match??? item=%p cursel=%d\n",\r
-                     item, cursel);\r
-               if (infoPtr->hwndEdit)\r
-                   SetFocus(infoPtr->hwndEdit);\r
-               return 0;\r
-           }\r
-       }\r
-\r
-       /* Save flags for testing and reset them */\r
-       oldflags = infoPtr->flags;\r
-       infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);\r
-\r
-       if (oldflags & WCBE_ACTEDIT) {\r
-           cbeend.fChanged = (oldflags & WCBE_EDITCHG);\r
-           cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,\r
-                                                CB_GETCURSEL, 0, 0);\r
-           cbeend.iWhy = CBENF_DROPDOWN;\r
-\r
-           if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, COMBOEX_GetText(infoPtr, item))) return 0;\r
-       }\r
-\r
-       /* if selection has changed the set the new current selection */\r
-       cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);\r
-       if ((oldflags & WCBE_EDITCHG) || (cursel != infoPtr->selected)) {\r
-           infoPtr->selected = cursel;\r
-           SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, cursel, 0);\r
-           SetFocus(infoPtr->hwndCombo);\r
-       }\r
-       return 0;\r
-\r
-    case CBN_SELCHANGE:\r
-       /*\r
-        * CB_GETCURSEL(Combo)\r
-        * CB_GETITEMDATA(Combo)   < simulated by COMBOEX_FindItem\r
-        * lstrlenA\r
-        * WM_SETTEXT(Edit)\r
-        * WM_GETTEXTLENGTH(Edit)\r
-        * WM_GETTEXT(Edit)\r
-        * EM_SETSEL(Edit, 0,0)\r
-        * WM_GETTEXTLENGTH(Edit)\r
-        * WM_GETTEXT(Edit)\r
-        * EM_SETSEL(Edit, 0,len)\r
-        * return WM_COMMAND to parent\r
-        */\r
-       oldItem = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);\r
-       if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) {\r
-           ERR("item %d not found. Problem!\n", oldItem);\r
-           break;\r
-       }\r
-       infoPtr->selected = oldItem;\r
-       COMBOEX_SetEditText (infoPtr, item);\r
-       return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);\r
-\r
-    case CBN_SELENDOK:\r
-       /*\r
-        * We have to change the handle since we are the control\r
-        * issuing the message. IE4 depends on this.\r
-        */\r
-       return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);\r
-\r
-    case CBN_KILLFOCUS:\r
-       /*\r
-        * from native trace:\r
-        *\r
-        *  pass to parent\r
-        *  WM_GETTEXT(Edit, 104)\r
-        *  CB_GETCURSEL(Combo) rets -1\r
-        *  WM_NOTIFY(CBEN_ENDEDITA) with CBENF_KILLFOCUS\r
-        *  CB_GETCURSEL(Combo)\r
-        *  InvalidateRect(Combo, 0, 0)\r
-        *  return 0\r
-        */\r
-       SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);\r
-       if (infoPtr->flags & WCBE_ACTEDIT) {\r
-           GetWindowTextW (infoPtr->hwndEdit, wintext, 260);\r
-           cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);\r
-           cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,\r
-                                                CB_GETCURSEL, 0, 0);\r
-           cbeend.iWhy = CBENF_KILLFOCUS;\r
-\r
-           infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);\r
-           if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, wintext)) return 0;\r
-       }\r
-       /* possible CB_GETCURSEL */\r
-       InvalidateRect (infoPtr->hwndCombo, 0, 0);\r
-       return 0;\r
-\r
-    default:\r
-       /*\r
-        * We have to change the handle since we are the control\r
-        * issuing the message. IE4 depends on this.\r
-        * We also need to set the focus back to the Edit control\r
-        * after passing the command to the parent of the ComboEx.\r
-        */\r
-       lret = SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);\r
-       if (infoPtr->hwndEdit)\r
-           SetFocus(infoPtr->hwndEdit);\r
-       return lret;\r
-    }\r
-    return 0;\r
-}\r
-\r
-\r
-static BOOL COMBOEX_WM_DeleteItem (COMBOEX_INFO *infoPtr, DELETEITEMSTRUCT *dis)\r
-{\r
-    CBE_ITEMDATA *item, *olditem;\r
-    NMCOMBOBOXEXW nmcit;\r
-    UINT i;\r
-\r
-    TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=%p, data=%08lx\n",\r
-         dis->CtlType, dis->CtlID, dis->itemID, dis->hwndItem, dis->itemData);\r
-\r
-    if (dis->itemID >= infoPtr->nb_items) return FALSE;\r
-\r
-    olditem = infoPtr->items;\r
-    i = infoPtr->nb_items - 1;\r
-\r
-    if (i == dis->itemID) {\r
-       infoPtr->items = infoPtr->items->next;\r
-    }\r
-    else {\r
-       item = olditem;\r
-       i--;\r
-\r
-       /* find the prior item in the list */\r
-       while (item->next && (i > dis->itemID)) {\r
-           item = (CBE_ITEMDATA *)item->next;\r
-           i--;\r
-       }\r
-       if (!item->next || (i != dis->itemID)) {\r
-           ERR("COMBOBOXEX item structures broken. Please report!\n");\r
-           return FALSE;\r
-       }\r
-       olditem = item->next;\r
-       item->next = (CBE_ITEMDATA *)((CBE_ITEMDATA *)item->next)->next;\r
-    }\r
-    infoPtr->nb_items--;\r
-\r
-    memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));\r
-    COMBOEX_CopyItem (olditem, &nmcit.ceItem);\r
-    COMBOEX_NotifyItem (infoPtr, CBEN_DELETEITEM, &nmcit);\r
-\r
-    COMBOEX_FreeText(olditem);\r
-    Free(olditem);\r
-\r
-    return TRUE;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_DrawItem (COMBOEX_INFO *infoPtr, DRAWITEMSTRUCT *dis)\r
-{\r
-    WCHAR nil[] = { 0 };\r
-    CBE_ITEMDATA *item = 0;\r
-    SIZE txtsize;\r
-    RECT rect;\r
-    LPCWSTR str = nil;\r
-    UINT xbase, x, y;\r
-    INT len;\r
-    COLORREF nbkc, ntxc, bkc, txc;\r
-    int drawimage, drawstate, xioff;\r
-\r
-    if (!IsWindowEnabled(infoPtr->hwndCombo)) return 0;\r
-\r
-    TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n",\r
-         dis->CtlType, dis->CtlID);\r
-    TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n",\r
-         dis->itemID, dis->itemAction, dis->itemState);\r
-    TRACE("hWnd=%p hDC=%p (%ld,%ld)-(%ld,%ld) itemData=0x%08lx\n",\r
-         dis->hwndItem, dis->hDC, dis->rcItem.left,\r
-         dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom,\r
-         dis->itemData);\r
-\r
-    /* MSDN says:                                                       */\r
-    /*     "itemID - Specifies the menu item identifier for a menu      */\r
-    /*      item or the index of the item in a list box or combo box.   */\r
-    /*      For an empty list box or combo box, this member can be -1.  */\r
-    /*      This allows the application to draw only the focus          */\r
-    /*      rectangle at the coordinates specified by the rcItem        */\r
-    /*      member even though there are no items in the control.       */\r
-    /*      This indicates to the user whether the list box or combo    */\r
-    /*      box has the focus. How the bits are set in the itemAction   */\r
-    /*      member determines whether the rectangle is to be drawn as   */\r
-    /*      though the list box or combo box has the focus.             */\r
-    if (dis->itemID == 0xffffffff) {\r
-       if ( ( (dis->itemAction & ODA_FOCUS) && (dis->itemState & ODS_SELECTED)) ||\r
-            ( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) {\r
-\r
-           TRACE("drawing item -1 special focus, rect=(%ld,%ld)-(%ld,%ld)\n",\r
-                 dis->rcItem.left, dis->rcItem.top,\r
-                 dis->rcItem.right, dis->rcItem.bottom);\r
-       }\r
-       else if ((dis->CtlType == ODT_COMBOBOX) &&\r
-                (dis->itemAction == ODA_DRAWENTIRE)) {\r
-           /* draw of edit control data */\r
-\r
-           /* testing */\r
-           {\r
-               RECT exrc, cbrc, edrc;\r
-               GetWindowRect (infoPtr->hwndSelf, &exrc);\r
-               GetWindowRect (infoPtr->hwndCombo, &cbrc);\r
-               edrc.left=edrc.top=edrc.right=edrc.bottom=-1;\r
-               if (infoPtr->hwndEdit)\r
-                   GetWindowRect (infoPtr->hwndEdit, &edrc);\r
-               TRACE("window rects ex=(%ld,%ld)-(%ld,%ld), cb=(%ld,%ld)-(%ld,%ld), ed=(%ld,%ld)-(%ld,%ld)\n",\r
-                     exrc.left, exrc.top, exrc.right, exrc.bottom,\r
-                     cbrc.left, cbrc.top, cbrc.right, cbrc.bottom,\r
-                     edrc.left, edrc.top, edrc.right, edrc.bottom);\r
-           }\r
-       }\r
-       else {\r
-           ERR("NOT drawing item  -1 special focus, rect=(%ld,%ld)-(%ld,%ld), action=%08x, state=%08x\n",\r
-               dis->rcItem.left, dis->rcItem.top,\r
-               dis->rcItem.right, dis->rcItem.bottom,\r
-               dis->itemAction, dis->itemState);\r
-           return 0;\r
-       }\r
-    }\r
-\r
-    /* If draw item is -1 (edit control) setup the item pointer */\r
-    if (dis->itemID == 0xffffffff) {\r
-       item = infoPtr->edit;\r
-\r
-       if (infoPtr->hwndEdit) {\r
-           INT len;\r
-\r
-           /* free previous text of edit item */\r
-           COMBOEX_FreeText(item);\r
-           item->mask &= ~CBEIF_TEXT;\r
-           if( (len = GetWindowTextLengthW(infoPtr->hwndEdit)) ) {\r
-               item->mask |= CBEIF_TEXT;\r
-               item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));\r
-               if (item->pszText)\r
-                   GetWindowTextW(infoPtr->hwndEdit, item->pszText, len+1);\r
-\r
-              TRACE("edit control hwndEdit=%p, text len=%d str=%s\n",\r
-                    infoPtr->hwndEdit, len, debugstr_txt(item->pszText));\r
-           }\r
-       }\r
-    }\r
-\r
-\r
-    /* if the item pointer is not set, then get the data and locate it */\r
-    if (!item) {\r
-        item = get_item_data(infoPtr, dis->itemID);\r
-       if (item == (CBE_ITEMDATA *)CB_ERR) {\r
-           ERR("invalid item for id %d \n", dis->itemID);\r
-           return 0;\r
-       }\r
-    }\r
-\r
-    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);\r
-\r
-    xbase = CBE_STARTOFFSET;\r
-    if ((item->mask & CBEIF_INDENT) && (dis->itemState & ODS_COMBOEXLBOX)) {\r
-       INT indent = item->iIndent;\r
-       if (indent == I_INDENTCALLBACK) {\r
-           NMCOMBOBOXEXW nmce;\r
-           ZeroMemory(&nmce, sizeof(nmce));\r
-           nmce.ceItem.mask = CBEIF_INDENT;\r
-           nmce.ceItem.lParam = item->lParam;\r
-           COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);\r
-           if (nmce.ceItem.mask & CBEIF_DI_SETITEM)\r
-               item->iIndent = nmce.ceItem.iIndent;\r
-           indent = nmce.ceItem.iIndent;\r
-       }\r
-        xbase += (indent * CBE_INDENT);\r
-    }\r
-\r
-    drawimage = -2;\r
-    drawstate = ILD_NORMAL;\r
-    if (item->mask & CBEIF_IMAGE)\r
-       drawimage = item->iImage;\r
-    if (dis->itemState & ODS_COMBOEXLBOX) {\r
-       /* drawing listbox entry */\r
-       if (dis->itemState & ODS_SELECTED) {\r
-           if (item->mask & CBEIF_SELECTEDIMAGE)\r
-               drawimage = item->iSelectedImage;\r
-           drawstate = ILD_SELECTED;\r
-       }\r
-    } else {\r
-       /* drawing combo/edit entry */\r
-       if (IsWindowVisible(infoPtr->hwndEdit)) {\r
-           /* if we have an edit control, the slave the\r
-             * selection state to the Edit focus state\r
-            */\r
-           if (infoPtr->flags & WCBE_EDITFOCUSED) {\r
-               if (item->mask & CBEIF_SELECTEDIMAGE)\r
-                   drawimage = item->iSelectedImage;\r
-               drawstate = ILD_SELECTED;\r
-           }\r
-       } else {\r
-           /* if we don't have an edit control, use\r
-            * the requested state.\r
-            */\r
-           if (dis->itemState & ODS_SELECTED) {\r
-               if (item->mask & CBEIF_SELECTEDIMAGE)\r
-                   drawimage = item->iSelectedImage;\r
-               drawstate = ILD_SELECTED;\r
-           }\r
-       }\r
-    }\r
-\r
-    if (infoPtr->himl && !(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGEINDENT)) {\r
-       IMAGEINFO iinfo;\r
-        iinfo.rcImage.left = iinfo.rcImage.right = 0;\r
-       ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo);\r
-       xioff = iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP;\r
-    }  else xioff = 0;\r
-\r
-    /* setup pointer to text to be drawn */\r
-    str = COMBOEX_GetText(infoPtr, item);\r
-    if (!str) str = nil;\r
-\r
-    len = strlenW (str);\r
-    GetTextExtentPoint32W (dis->hDC, str, len, &txtsize);\r
-\r
-    if (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) {\r
-       int overlay = item->iOverlay;\r
-\r
-       if (drawimage == I_IMAGECALLBACK) {\r
-           NMCOMBOBOXEXW nmce;\r
-           ZeroMemory(&nmce, sizeof(nmce));\r
-           nmce.ceItem.mask = (drawstate == ILD_NORMAL) ? CBEIF_IMAGE : CBEIF_SELECTEDIMAGE;\r
-           nmce.ceItem.lParam = item->lParam;\r
-           COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);\r
-           if (drawstate == ILD_NORMAL) {\r
-               if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iImage = nmce.ceItem.iImage;\r
-               drawimage = nmce.ceItem.iImage;\r
-           } else if (drawstate == ILD_SELECTED) {\r
-               if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iSelectedImage = nmce.ceItem.iSelectedImage;\r
-               drawimage =  nmce.ceItem.iSelectedImage;\r
-           } else ERR("Bad draw state = %d\n", drawstate);\r
-        }\r
-\r
-       if (overlay == I_IMAGECALLBACK) {\r
-           NMCOMBOBOXEXW nmce;\r
-           ZeroMemory(&nmce, sizeof(nmce));\r
-           nmce.ceItem.mask = CBEIF_OVERLAY;\r
-           nmce.ceItem.lParam = item->lParam;\r
-           COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);\r
-           if (nmce.ceItem.mask & CBEIF_DI_SETITEM)\r
-               item->iOverlay = nmce.ceItem.iOverlay;\r
-           overlay = nmce.ceItem.iOverlay;\r
-       }\r
-\r
-       if (drawimage >= 0 &&\r
-           !(infoPtr->dwExtStyle & (CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT))) {\r
-           if (overlay > 0) ImageList_SetOverlayImage (infoPtr->himl, overlay, 1);\r
-           ImageList_Draw (infoPtr->himl, drawimage, dis->hDC, xbase, dis->rcItem.top,\r
-                           drawstate | (overlay > 0 ? INDEXTOOVERLAYMASK(1) : 0));\r
-       }\r
-\r
-       /* now draw the text */\r
-       if (!IsWindowVisible (infoPtr->hwndEdit)) {\r
-           nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ?\r
-                               COLOR_HIGHLIGHT : COLOR_WINDOW);\r
-           bkc = SetBkColor (dis->hDC, nbkc);\r
-           ntxc = GetSysColor ((dis->itemState & ODS_SELECTED) ?\r
-                               COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);\r
-           txc = SetTextColor (dis->hDC, ntxc);\r
-           x = xbase + xioff;\r
-           y = dis->rcItem.top +\r
-               (dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;\r
-           rect.left = x;\r
-           rect.right = x + txtsize.cx;\r
-           rect.top = dis->rcItem.top + 1;\r
-           rect.bottom = dis->rcItem.bottom - 1;\r
-           TRACE("drawing item %d text, rect=(%ld,%ld)-(%ld,%ld)\n",\r
-                 dis->itemID, rect.left, rect.top, rect.right, rect.bottom);\r
-           ExtTextOutW (dis->hDC, x, y, ETO_OPAQUE | ETO_CLIPPED,\r
-                        &rect, str, len, 0);\r
-           SetBkColor (dis->hDC, bkc);\r
-           SetTextColor (dis->hDC, txc);\r
-       }\r
-    }\r
-\r
-    if (dis->itemAction & ODA_FOCUS) {\r
-       rect.left = xbase + xioff - 1;\r
-       rect.right = rect.left + txtsize.cx + 2;\r
-       rect.top = dis->rcItem.top;\r
-       rect.bottom = dis->rcItem.bottom;\r
-       DrawFocusRect(dis->hDC, &rect);\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr)\r
-{\r
-    if (infoPtr->hwndCombo)\r
-       DestroyWindow (infoPtr->hwndCombo);\r
-\r
-    if (infoPtr->edit) {\r
-       Free (infoPtr->edit);\r
-       infoPtr->edit = 0;\r
-    }\r
-\r
-    if (infoPtr->items) {\r
-        CBE_ITEMDATA *item, *next;\r
-\r
-       item = infoPtr->items;\r
-       while (item) {\r
-           next = (CBE_ITEMDATA *)item->next;\r
-           COMBOEX_FreeText (item);\r
-           Free (item);\r
-           item = next;\r
-       }\r
-       infoPtr->items = 0;\r
-    }\r
-\r
-    if (infoPtr->defaultFont)\r
-       DeleteObject (infoPtr->defaultFont);\r
-\r
-    /* free comboex info data */\r
-    Free (infoPtr);\r
-    SetWindowLongW (infoPtr->hwndSelf, 0, 0);\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_MeasureItem (COMBOEX_INFO *infoPtr, MEASUREITEMSTRUCT *mis)\r
-{\r
-    SIZE mysize;\r
-    HDC hdc;\r
-\r
-    hdc = GetDC (0);\r
-    GetTextExtentPointA (hdc, "W", 1, &mysize);\r
-    ReleaseDC (0, hdc);\r
-    mis->itemHeight = mysize.cy + CBE_EXTRA;\r
-\r
-    TRACE("adjusted height hwnd=%p, height=%d\n",\r
-         infoPtr->hwndSelf, mis->itemHeight);\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_NCCreate (HWND hwnd)\r
-{\r
-    /* WARNING: The COMBOEX_INFO structure is not yet created */\r
-    DWORD oldstyle, newstyle;\r
-\r
-    oldstyle = (DWORD)GetWindowLongW (hwnd, GWL_STYLE);\r
-    newstyle = oldstyle & ~(WS_VSCROLL | WS_HSCROLL);\r
-    if (newstyle != oldstyle) {\r
-       TRACE("req style %08lx, reseting style %08lx\n",\r
-             oldstyle, newstyle);\r
-       SetWindowLongW (hwnd, GWL_STYLE, newstyle);\r
-    }\r
-    return 1;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_NotifyFormat (COMBOEX_INFO *infoPtr, LPARAM lParam)\r
-{\r
-    if (lParam == NF_REQUERY) {\r
-       INT i = SendMessageW(GetParent (infoPtr->hwndSelf),\r
-                        WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);\r
-       infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;\r
-    }\r
-    return infoPtr->NtfUnicode ? NFR_UNICODE : NFR_ANSI;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_Size (COMBOEX_INFO *infoPtr, INT width, INT height)\r
-{\r
-    TRACE("(width=%d, height=%d)\n", width, height);\r
-\r
-    MoveWindow (infoPtr->hwndCombo, 0, 0, width, height, TRUE);\r
-\r
-    COMBOEX_AdjustEditPos (infoPtr);\r
-\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT COMBOEX_WindowPosChanging (COMBOEX_INFO *infoPtr, WINDOWPOS *wp)\r
-{\r
-    RECT cbx_wrect, cbx_crect, cb_wrect;\r
-    UINT width, height;\r
-\r
-    GetWindowRect (infoPtr->hwndSelf, &cbx_wrect);\r
-    GetClientRect (infoPtr->hwndSelf, &cbx_crect);\r
-    GetWindowRect (infoPtr->hwndCombo, &cb_wrect);\r
-\r
-    /* width is winpos value + border width of comboex */\r
-    width = wp->cx\r
-           + (cbx_wrect.right-cbx_wrect.left)\r
-            - (cbx_crect.right-cbx_crect.left);\r
-\r
-    TRACE("winpos=(%d,%d %dx%d) flags=0x%08x\n",\r
-         wp->x, wp->y, wp->cx, wp->cy, wp->flags);\r
-    TRACE("EX window=(%ld,%ld)-(%ld,%ld), client=(%ld,%ld)-(%ld,%ld)\n",\r
-         cbx_wrect.left, cbx_wrect.top, cbx_wrect.right, cbx_wrect.bottom,\r
-         cbx_crect.left, cbx_crect.top, cbx_crect.right, cbx_crect.bottom);\r
-    TRACE("CB window=(%ld,%ld)-(%ld,%ld), EX setting=(0,0)-(%d,%ld)\n",\r
-         cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom,\r
-         width, cb_wrect.bottom-cb_wrect.top);\r
-\r
-    if (width) SetWindowPos (infoPtr->hwndCombo, HWND_TOP, 0, 0,\r
-                            width,\r
-                            cb_wrect.bottom-cb_wrect.top,\r
-                            SWP_NOACTIVATE);\r
-\r
-    GetWindowRect (infoPtr->hwndCombo, &cb_wrect);\r
-\r
-    /* height is combo window height plus border width of comboex */\r
-    height =   (cb_wrect.bottom-cb_wrect.top)\r
-            + (cbx_wrect.bottom-cbx_wrect.top)\r
-             - (cbx_crect.bottom-cbx_crect.top);\r
-    if (wp->cy < height) wp->cy = height;\r
-    if (infoPtr->hwndEdit) {\r
-       COMBOEX_AdjustEditPos (infoPtr);\r
-       InvalidateRect (infoPtr->hwndCombo, 0, TRUE);\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-static inline int is_delimiter(WCHAR c)\r
-{\r
-    switch(c) {\r
-       case '/':\r
-       case '\\':\r
-       case '.':\r
-           return TRUE;\r
-    }\r
-    return FALSE;\r
-}\r
-\r
-static int CALLBACK\r
-COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)\r
-{\r
-    if (code == WB_ISDELIMITER) {\r
-       return is_delimiter(lpch[ichCurrent]);\r
-    } else {\r
-       int dir = (code == WB_LEFT) ? -1 : 1;\r
-        for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)\r
-           if (is_delimiter(lpch[ichCurrent])) return ichCurrent;\r
-    }\r
-    return ichCurrent;\r
-}\r
-\r
-static LRESULT WINAPI\r
-COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-    HWND hwndComboex = (HWND)GetPropA(hwnd, COMBOEX_SUBCLASS_PROP);\r
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwndComboex);\r
-    NMCBEENDEDITW cbeend;\r
-    WCHAR edit_text[260];\r
-    COLORREF obkc;\r
-    HDC hDC;\r
-    RECT rect;\r
-    LRESULT lret;\r
-\r
-    TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",\r
-         hwnd, uMsg, wParam, lParam, infoPtr);\r
-\r
-    if (!infoPtr) return 0;\r
-\r
-    switch (uMsg)\r
-    {\r
-\r
-       case WM_CHAR:\r
-           /* handle (ignore) the return character */\r
-           if (wParam == VK_RETURN) return 0;\r
-           /* all other characters pass into the real Edit */\r
-           return CallWindowProcW (infoPtr->prevEditWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-\r
-       case WM_ERASEBKGND:\r
-           /*\r
-            * The following was determined by traces of the native\r
-            */\r
-            hDC = (HDC) wParam;\r
-           obkc = SetBkColor (hDC, GetSysColor (COLOR_WINDOW));\r
-            GetClientRect (hwnd, &rect);\r
-           TRACE("erasing (%ld,%ld)-(%ld,%ld)\n",\r
-                 rect.left, rect.top, rect.right, rect.bottom);\r
-           ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);\r
-            SetBkColor (hDC, obkc);\r
-           return CallWindowProcW (infoPtr->prevEditWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-\r
-       case WM_KEYDOWN: {\r
-           INT oldItem, selected, step = 1;\r
-           CBE_ITEMDATA *item;\r
-\r
-           switch ((INT)wParam)\r
-           {\r
-           case VK_ESCAPE:\r
-               /* native version seems to do following for COMBOEX */\r
-               /*\r
-                *   GetWindowTextA(Edit,&?, 0x104)             x\r
-                *   CB_GETCURSEL to Combo rets -1              x\r
-                *   WM_NOTIFY to COMBOEX parent (rebar)        x\r
-                *     (CBEN_ENDEDIT{A|W}\r
-                *      fChanged = FALSE                        x\r
-                *      inewSelection = -1                      x\r
-                *      txt="www.hoho"                          x\r
-                *      iWhy = 3                                x\r
-                *   CB_GETCURSEL to Combo rets -1              x\r
-                *   InvalidateRect(Combo, 0)                   x\r
-                *   WM_SETTEXT to Edit                         x\r
-                *   EM_SETSEL to Edit (0,0)                    x\r
-                *   EM_SETSEL to Edit (0,-1)                   x\r
-                *   RedrawWindow(Combo, 0, 0, 5)               x\r
-                */\r
-               TRACE("special code for VK_ESCAPE\n");\r
-\r
-               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);\r
-\r
-               infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);\r
-               cbeend.fChanged = FALSE;\r
-               cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,\r
-                                                    CB_GETCURSEL, 0, 0);\r
-               cbeend.iWhy = CBENF_ESCAPE;\r
-\r
-               if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) return 0;\r
-               oldItem = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);\r
-               InvalidateRect (infoPtr->hwndCombo, 0, 0);\r
-               if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) {\r
-                   ERR("item %d not found. Problem!\n", oldItem);\r
-                   break;\r
-               }\r
-               infoPtr->selected = oldItem;\r
-               COMBOEX_SetEditText (infoPtr, item);\r
-               RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE |\r
-                             RDW_INVALIDATE);\r
-               break;\r
-\r
-           case VK_RETURN:\r
-               /* native version seems to do following for COMBOEX */\r
-               /*\r
-                *   GetWindowTextA(Edit,&?, 0x104)             x\r
-                *   CB_GETCURSEL to Combo  rets -1             x\r
-                *   CB_GETCOUNT to Combo  rets 0\r
-                *   if >0 loop\r
-                *       CB_GETITEMDATA to match\r
-                * *** above 3 lines simulated by FindItem      x\r
-                *   WM_NOTIFY to COMBOEX parent (rebar)        x\r
-                *     (CBEN_ENDEDIT{A|W}                       x\r
-                *        fChanged = TRUE (-1)                  x\r
-                *        iNewSelection = -1 or selected        x\r
-                *        txt=                                  x\r
-                *        iWhy = 2 (CBENF_RETURN)               x\r
-                *   CB_GETCURSEL to Combo  rets -1             x\r
-                *   if -1 send CB_SETCURSEL to Combo -1        x\r
-                *   InvalidateRect(Combo, 0, 0)                x\r
-                *   SetFocus(Edit)                             x\r
-                *   CallWindowProc(406615a8, Edit, 0x100, 0xd, 0x1c0001)\r
-                */\r
-\r
-               TRACE("special code for VK_RETURN\n");\r
-\r
-               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);\r
-\r
-               infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);\r
-               selected = SendMessageW (infoPtr->hwndCombo,\r
-                                        CB_GETCURSEL, 0, 0);\r
-\r
-               if (selected != -1) {\r
-                    cmp_func_t cmptext = get_cmp_func(infoPtr);\r
-                   item = COMBOEX_FindItem (infoPtr, selected);\r
-                   TRACE("handling VK_RETURN, selected = %d, selected_text=%s\n",\r
-                         selected, debugstr_txt(item->pszText));\r
-                   TRACE("handling VK_RETURN, edittext=%s\n",\r
-                         debugstr_w(edit_text));\r
-                   if (cmptext (COMBOEX_GetText(infoPtr, item), edit_text)) {\r
-                       /* strings not equal -- indicate edit has changed */\r
-                       selected = -1;\r
-                   }\r
-               }\r
-\r
-               cbeend.iNewSelection = selected;\r
-               cbeend.fChanged = TRUE;\r
-               cbeend.iWhy = CBENF_RETURN;\r
-               if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) {\r
-                   /* abort the change, restore previous */\r
-                   TRACE("Notify requested abort of change\n");\r
-                   COMBOEX_SetEditText (infoPtr, infoPtr->edit);\r
-                   RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE |\r
-                                 RDW_INVALIDATE);\r
-                   return 0;\r
-               }\r
-               oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);\r
-               if (oldItem != -1) {\r
-                   /* if something is selected, then deselect it */\r
-                   SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL,\r
-                                 (WPARAM)-1, 0);\r
-               }\r
-               InvalidateRect (infoPtr->hwndCombo, 0, 0);\r
-               SetFocus(infoPtr->hwndEdit);\r
-               break;\r
-\r
-           case VK_UP:\r
-               step = -1;\r
-           case VK_DOWN:\r
-               /* by default, step is 1 */\r
-               oldItem = SendMessageW (infoPtr->hwndSelf, CB_GETCURSEL, 0, 0);\r
-               if (oldItem >= 0 && oldItem + step >= 0)\r
-                   SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, oldItem + step, 0);\r
-               return 0;\r
-           default:\r
-               return CallWindowProcW (infoPtr->prevEditWndProc,\r
-                                      hwnd, uMsg, wParam, lParam);\r
-           }\r
-           return 0;\r
-            }\r
-\r
-       case WM_SETFOCUS:\r
-           /* remember the focus to set state of icon */\r
-           lret = CallWindowProcW (infoPtr->prevEditWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-           infoPtr->flags |= WCBE_EDITFOCUSED;\r
-           return lret;\r
-\r
-       case WM_KILLFOCUS:\r
-           /*\r
-            * do NOTIFY CBEN_ENDEDIT with CBENF_KILLFOCUS\r
-            */\r
-           infoPtr->flags &= ~WCBE_EDITFOCUSED;\r
-           if (infoPtr->flags & WCBE_ACTEDIT) {\r
-               infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);\r
-\r
-               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);\r
-               cbeend.fChanged = FALSE;\r
-               cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,\r
-                                                    CB_GETCURSEL, 0, 0);\r
-               cbeend.iWhy = CBENF_KILLFOCUS;\r
-\r
-               COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text);\r
-           }\r
-           /* fall through */\r
-\r
-       default:\r
-           return CallWindowProcW (infoPtr->prevEditWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-    }\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT WINAPI\r
-COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-    HWND hwndComboex = (HWND)GetPropA(hwnd, COMBOEX_SUBCLASS_PROP);\r
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwndComboex);\r
-    NMCBEENDEDITW cbeend;\r
-    NMMOUSE nmmse;\r
-    COLORREF obkc;\r
-    HDC hDC;\r
-    HWND focusedhwnd;\r
-    RECT rect;\r
-    POINT pt;\r
-    WCHAR edit_text[260];\r
-\r
-    TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",\r
-         hwnd, uMsg, wParam, lParam, infoPtr);\r
-\r
-    if (!infoPtr) return 0;\r
-\r
-    switch (uMsg)\r
-    {\r
-\r
-    case WM_DRAWITEM:\r
-           /*\r
-            * The only way this message should come is from the\r
-            * child Listbox issuing the message. Flag this so\r
-            * that ComboEx knows this is listbox.\r
-            */\r
-           ((DRAWITEMSTRUCT *)lParam)->itemState |= ODS_COMBOEXLBOX;\r
-           return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_ERASEBKGND:\r
-           /*\r
-            * The following was determined by traces of the native\r
-            */\r
-            hDC = (HDC) wParam;\r
-           obkc = SetBkColor (hDC, GetSysColor (COLOR_WINDOW));\r
-            GetClientRect (hwnd, &rect);\r
-           TRACE("erasing (%ld,%ld)-(%ld,%ld)\n",\r
-                 rect.left, rect.top, rect.right, rect.bottom);\r
-           ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);\r
-            SetBkColor (hDC, obkc);\r
-           return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_SETCURSOR:\r
-           /*\r
-            *  WM_NOTIFY to comboex parent (rebar)\r
-            *   with NM_SETCURSOR with extra words of 0,0,0,0,0x02010001\r
-            *  CallWindowProc (previous)\r
-            */\r
-           nmmse.dwItemSpec = 0;\r
-           nmmse.dwItemData = 0;\r
-           nmmse.pt.x = 0;\r
-           nmmse.pt.y = 0;\r
-           nmmse.dwHitInfo = lParam;\r
-           COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse);\r
-           return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_LBUTTONDOWN:\r
-           GetClientRect (hwnd, &rect);\r
-           rect.bottom = rect.top + SendMessageW(infoPtr->hwndSelf,\r
-                                                 CB_GETITEMHEIGHT, -1, 0);\r
-           rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL);\r
-           POINTSTOPOINT(pt, MAKEPOINTS(lParam));\r
-           if (PtInRect(&rect, pt))\r
-               return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                       hwnd, uMsg, wParam, lParam);\r
-           infoPtr->flags |= WCBE_MOUSECAPTURED;\r
-           SetCapture(hwnd);\r
-           break;\r
-\r
-    case WM_LBUTTONUP:\r
-           if (!(infoPtr->flags & WCBE_MOUSECAPTURED))\r
-               return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                       hwnd, uMsg, wParam, lParam);\r
-           ReleaseCapture();\r
-           infoPtr->flags &= ~WCBE_MOUSECAPTURED;\r
-           if (infoPtr->flags & WCBE_MOUSEDRAGGED) {\r
-               infoPtr->flags &= ~WCBE_MOUSEDRAGGED;\r
-           } else {\r
-               SendMessageW(hwnd, CB_SHOWDROPDOWN, TRUE, 0);\r
-           }\r
-           break;\r
-\r
-    case WM_MOUSEMOVE:\r
-           if ( (infoPtr->flags & WCBE_MOUSECAPTURED) &&\r
-               !(infoPtr->flags & WCBE_MOUSEDRAGGED)) {\r
-               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);\r
-               COMBOEX_NotifyDragBegin(infoPtr, edit_text);\r
-               infoPtr->flags |= WCBE_MOUSEDRAGGED;\r
-           }\r
-           return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                   hwnd, uMsg, wParam, lParam);\r
-\r
-    case WM_COMMAND:\r
-           switch (HIWORD(wParam)) {\r
-\r
-           case EN_UPDATE:\r
-               /* traces show that COMBOEX does not issue CBN_EDITUPDATE\r
-                * on the EN_UPDATE\r
-                */\r
-               return 0;\r
-\r
-           case EN_KILLFOCUS:\r
-               /*\r
-                * Native does:\r
-                *\r
-                *  GetFocus() retns AA\r
-                *  GetWindowTextA(Edit)\r
-                *  CB_GETCURSEL(Combo) (got -1)\r
-                *  WM_NOTIFY(CBEN_ENDEDITA) with CBENF_KILLFOCUS\r
-                *  CB_GETCURSEL(Combo) (got -1)\r
-                *  InvalidateRect(Combo, 0, 0)\r
-                *  WM_KILLFOCUS(Combo, AA)\r
-                *  return 0;\r
-                */\r
-               focusedhwnd = GetFocus();\r
-               if (infoPtr->flags & WCBE_ACTEDIT) {\r
-                   GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);\r
-                   cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);\r
-                   cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,\r
-                                                        CB_GETCURSEL, 0, 0);\r
-                   cbeend.iWhy = CBENF_KILLFOCUS;\r
-\r
-                   infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);\r
-                   if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) return 0;\r
-               }\r
-               /* possible CB_GETCURSEL */\r
-               InvalidateRect (infoPtr->hwndCombo, 0, 0);\r
-               if (focusedhwnd)\r
-                   SendMessageW (infoPtr->hwndCombo, WM_KILLFOCUS,\r
-                                 (WPARAM)focusedhwnd, 0);\r
-               return 0;\r
-\r
-           case EN_SETFOCUS: {\r
-               /*\r
-                * For EN_SETFOCUS this issues the same calls and messages\r
-                *  as the native seems to do.\r
-                *\r
-                * for some cases however native does the following:\r
-                *   (noticed after SetFocus during LBUTTONDOWN on\r
-                *    on dropdown arrow)\r
-                *  WM_GETTEXTLENGTH (Edit);\r
-                *  WM_GETTEXT (Edit, len+1, str);\r
-                *  EM_SETSEL (Edit, 0, 0);\r
-                *  WM_GETTEXTLENGTH (Edit);\r
-                *  WM_GETTEXT (Edit, len+1, str);\r
-                *  EM_SETSEL (Edit, 0, len);\r
-                *  WM_NOTIFY (parent, CBEN_BEGINEDIT)\r
-                */\r
-               NMHDR hdr;\r
-\r
-               SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);\r
-               SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);\r
-               COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr);\r
-               infoPtr->flags |= WCBE_ACTEDIT;\r
-               infoPtr->flags &= ~WCBE_EDITCHG; /* no change yet */\r
-               return 0;\r
-               }\r
-\r
-           case EN_CHANGE: {\r
-               /*\r
-                * For EN_CHANGE this issues the same calls and messages\r
-                *  as the native seems to do.\r
-                */\r
-               WCHAR edit_text[260];\r
-               LPCWSTR lastwrk;\r
-                cmp_func_t cmptext = get_cmp_func(infoPtr);\r
-\r
-               INT selected = SendMessageW (infoPtr->hwndCombo,\r
-                                            CB_GETCURSEL, 0, 0);\r
-\r
-               /* lstrlenA( lastworkingURL ) */\r
-\r
-               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);\r
-               if (selected == -1) {\r
-                   lastwrk = infoPtr->edit->pszText;\r
-               }\r
-               else {\r
-                   CBE_ITEMDATA *item = COMBOEX_FindItem (infoPtr, selected);\r
-                   lastwrk = COMBOEX_GetText(infoPtr, item);\r
-               }\r
-\r
-               TRACE("handling EN_CHANGE, selected = %d, selected_text=%s\n",\r
-                     selected, debugstr_w(lastwrk));\r
-               TRACE("handling EN_CHANGE, edittext=%s\n",\r
-                     debugstr_w(edit_text));\r
-\r
-               /* cmptext is between lastworkingURL and GetWindowText */\r
-               if (cmptext (lastwrk, edit_text)) {\r
-                   /* strings not equal -- indicate edit has changed */\r
-                   infoPtr->flags |= WCBE_EDITCHG;\r
-               }\r
-               SendMessageW ( GetParent(infoPtr->hwndSelf), WM_COMMAND,\r
-                              MAKEWPARAM(GetDlgCtrlID (infoPtr->hwndSelf),\r
-                                         CBN_EDITCHANGE),\r
-                              (LPARAM)infoPtr->hwndSelf);\r
-               return 0;\r
-               }\r
-\r
-           case LBN_SELCHANGE:\r
-               /*\r
-                * Therefore from traces there is no additional code here\r
-                */\r
-\r
-               /*\r
-                * Using native COMCTL32 gets the following:\r
-                *  1 == SHDOCVW.DLL  issues call/message\r
-                *  2 == COMCTL32.DLL  issues call/message\r
-                *  3 == WINE  issues call/message\r
-                *\r
-                *\r
-                * for LBN_SELCHANGE:\r
-                *    1  CB_GETCURSEL(ComboEx)\r
-                *    1  CB_GETDROPPEDSTATE(ComboEx)\r
-                *    1  CallWindowProc( *2* for WM_COMMAND(LBN_SELCHANGE)\r
-                *    2  CallWindowProc( *3* for WM_COMMAND(LBN_SELCHANGE)\r
-                **   call CBRollUp( xxx, TRUE for LBN_SELCHANGE, TRUE)\r
-                *    3  WM_COMMAND(ComboEx, CBN_SELENDOK)\r
-                *      WM_USER+49(ComboLB, 1,0)  <=============!!!!!!!!!!!\r
-                *    3  ShowWindow(ComboLB, SW_HIDE)\r
-                *    3  RedrawWindow(Combo,  RDW_UPDATENOW)\r
-                *    3  WM_COMMAND(ComboEX, CBN_CLOSEUP)\r
-                **   end of CBRollUp\r
-                *    3  WM_COMMAND(ComboEx, CBN_SELCHANGE)  (echo to parent)\r
-                *    ?  LB_GETCURSEL              <==|\r
-                *    ?  LB_GETTEXTLEN                |\r
-                *    ?  LB_GETTEXT                   | Needs to be added to\r
-                *    ?  WM_CTLCOLOREDIT(ComboEx)     | Combo processing\r
-                *    ?  LB_GETITEMDATA               |\r
-                *    ?  WM_DRAWITEM(ComboEx)      <==|\r
-                */\r
-           default:\r
-               break;\r
-           }/* fall through */\r
-    default:\r
-           return CallWindowProcW (infoPtr->prevComboWndProc,\r
-                                  hwnd, uMsg, wParam, lParam);\r
-    }\r
-    return 0;\r
-}\r
-\r
-\r
-static LRESULT WINAPI\r
-COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
-    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);\r
-\r
-    TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);\r
-\r
-    if (!infoPtr) {\r
-       if (uMsg == WM_CREATE)\r
-           return COMBOEX_Create (hwnd, (LPCREATESTRUCTA)lParam);\r
-       if (uMsg == WM_NCCREATE)\r
-           COMBOEX_NCCreate (hwnd);\r
-        return DefWindowProcW (hwnd, uMsg, wParam, lParam);\r
-    }\r
-\r
-    switch (uMsg)\r
-    {\r
-        case CBEM_DELETEITEM:\r
-           return COMBOEX_DeleteItem (infoPtr, wParam);\r
-\r
-       case CBEM_GETCOMBOCONTROL:\r
-           return (LRESULT)infoPtr->hwndCombo;\r
-\r
-       case CBEM_GETEDITCONTROL:\r
-           return (LRESULT)infoPtr->hwndEdit;\r
-\r
-       case CBEM_GETEXTENDEDSTYLE:\r
-           return infoPtr->dwExtStyle;\r
-\r
-       case CBEM_GETIMAGELIST:\r
-           return (LRESULT)infoPtr->himl;\r
-\r
-       case CBEM_GETITEMA:\r
-           return (LRESULT)COMBOEX_GetItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);\r
-\r
-       case CBEM_GETITEMW:\r
-           return (LRESULT)COMBOEX_GetItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);\r
-\r
-       case CBEM_GETUNICODEFORMAT:\r
-           return infoPtr->unicode;\r
-\r
-       case CBEM_HASEDITCHANGED:\r
-           return COMBOEX_HasEditChanged (infoPtr);\r
-\r
-       case CBEM_INSERTITEMA:\r
-           return COMBOEX_InsertItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);\r
-\r
-       case CBEM_INSERTITEMW:\r
-           return COMBOEX_InsertItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);\r
-\r
-       case CBEM_SETEXSTYLE:\r
-       case CBEM_SETEXTENDEDSTYLE:\r
-           return COMBOEX_SetExtendedStyle (infoPtr, (DWORD)wParam, (DWORD)lParam);\r
-\r
-       case CBEM_SETIMAGELIST:\r
-           return (LRESULT)COMBOEX_SetImageList (infoPtr, (HIMAGELIST)lParam);\r
-\r
-       case CBEM_SETITEMA:\r
-           return COMBOEX_SetItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);\r
-\r
-       case CBEM_SETITEMW:\r
-           return COMBOEX_SetItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);\r
-\r
-       case CBEM_SETUNICODEFORMAT:\r
-           return COMBOEX_SetUnicodeFormat (infoPtr, wParam);\r
-\r
-       /*case CBEM_SETWINDOWTHEME:\r
-           FIXME("CBEM_SETWINDOWTHEME: stub\n");*/\r
-\r
-       case WM_SETTEXT:\r
-       case WM_GETTEXT:\r
-            return SendMessageW(infoPtr->hwndEdit, uMsg, wParam, lParam);\r
-\r
-/*   Combo messages we are not sure if we need to process or just forward */\r
-       case CB_GETDROPPEDCONTROLRECT:\r
-       case CB_GETITEMHEIGHT:\r
-       case CB_GETLBTEXT:\r
-       case CB_GETLBTEXTLEN:\r
-       case CB_GETEXTENDEDUI:\r
-       case CB_LIMITTEXT:\r
-       case CB_RESETCONTENT:\r
-       case CB_SELECTSTRING:\r
-\r
-/*   Combo messages OK to just forward to the regular COMBO */\r
-       case CB_GETCOUNT:\r
-       case CB_GETCURSEL:\r
-       case CB_GETDROPPEDSTATE:\r
-        case CB_SETDROPPEDWIDTH:\r
-        case CB_SETEXTENDEDUI:\r
-        case CB_SHOWDROPDOWN:\r
-           return SendMessageW (infoPtr->hwndCombo, uMsg, wParam, lParam);\r
-\r
-/*   Combo messages we need to process specially */\r
-        case CB_FINDSTRINGEXACT:\r
-           return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPCWSTR)lParam);\r
-\r
-       case CB_GETITEMDATA:\r
-           return COMBOEX_GetItemData (infoPtr, (INT)wParam);\r
-\r
-       case CB_SETCURSEL:\r
-           return COMBOEX_SetCursel (infoPtr, (INT)wParam);\r
-\r
-       case CB_SETITEMDATA:\r
-           return COMBOEX_SetItemData (infoPtr, (INT)wParam, (DWORD)lParam);\r
-\r
-       case CB_SETITEMHEIGHT:\r
-           return COMBOEX_SetItemHeight (infoPtr, (INT)wParam, (UINT)lParam);\r
-\r
-\r
-\r
-/*   Window messages passed to parent */\r
-       case WM_COMMAND:\r
-           return COMBOEX_Command (infoPtr, wParam, lParam);\r
-\r
-       case WM_NOTIFY:\r
-           if (infoPtr->NtfUnicode)\r
-               return SendMessageW (GetParent (hwnd), uMsg, wParam, lParam);\r
-           else\r
-               return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);\r
-\r
-\r
-/*   Window messages we need to process */\r
-        case WM_DELETEITEM:\r
-           return COMBOEX_WM_DeleteItem (infoPtr, (DELETEITEMSTRUCT *)lParam);\r
-\r
-        case WM_DRAWITEM:\r
-            return COMBOEX_DrawItem (infoPtr, (DRAWITEMSTRUCT *)lParam);\r
-\r
-       case WM_DESTROY:\r
-           return COMBOEX_Destroy (infoPtr);\r
-\r
-        case WM_MEASUREITEM:\r
-            return COMBOEX_MeasureItem (infoPtr, (MEASUREITEMSTRUCT *)lParam);\r
-\r
-        case WM_NOTIFYFORMAT:\r
-           return COMBOEX_NotifyFormat (infoPtr, lParam);\r
-\r
-       case WM_SIZE:\r
-           return COMBOEX_Size (infoPtr, LOWORD(lParam), HIWORD(lParam));\r
-\r
-        case WM_WINDOWPOSCHANGING:\r
-           return COMBOEX_WindowPosChanging (infoPtr, (WINDOWPOS *)lParam);\r
-\r
-       default:\r
-           if ((uMsg >= WM_USER) && (uMsg < WM_APP))\r
-               ERR("unknown msg %04x wp=%08x lp=%08lx\n",uMsg,wParam,lParam);\r
-           return DefWindowProcW (hwnd, uMsg, wParam, lParam);\r
-    }\r
-    return 0;\r
-}\r
-\r
-\r
-void COMBOEX_Register (void)\r
-{\r
-    WNDCLASSW wndClass;\r
-\r
-    ZeroMemory (&wndClass, sizeof(WNDCLASSW));\r
-    wndClass.style         = CS_GLOBALCLASS;\r
-    wndClass.lpfnWndProc   = (WNDPROC)COMBOEX_WindowProc;\r
-    wndClass.cbClsExtra    = 0;\r
-    wndClass.cbWndExtra    = sizeof(COMBOEX_INFO *);\r
-    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);\r
-    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);\r
-    wndClass.lpszClassName = WC_COMBOBOXEXW;\r
-\r
-    RegisterClassW (&wndClass);\r
-}\r
-\r
-\r
-void COMBOEX_Unregister (void)\r
-{\r
-    UnregisterClassW (WC_COMBOBOXEXW, NULL);\r
-}\r
+/*
+ * ComboBoxEx control
+ *
+ * Copyright 1998, 1999 Eric Kohl
+ * Copyright 2000, 2001, 2002 Guy Albertelli <galberte@neo.lrun.com>
+ * Copyright 2002 Dimitrie O. Paun
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * NOTE
+ * 
+ * This code was audited for completeness against the documented features
+ * of Comctl32.dll version 6.0 on Sep. 9, 2002, by Dimitrie O. Paun.
+ * 
+ * Unless otherwise noted, we belive this code to be complete, as per
+ * the specification mentioned above.
+ * If you discover missing features, or bugs, please note them below.
+ * 
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "commctrl.h"
+#include "comctl32.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(comboex);
+
+/* Item structure */
+typedef struct
+{
+    VOID         *next;
+    UINT         mask;
+    LPWSTR       pszText;
+    LPWSTR       pszTemp;
+    int          cchTextMax;
+    int          iImage;
+    int          iSelectedImage;
+    int          iOverlay;
+    int          iIndent;
+    LPARAM       lParam;
+} CBE_ITEMDATA;
+
+/* ComboBoxEx structure */
+typedef struct
+{
+    HIMAGELIST   himl;
+    HWND         hwndSelf;         /* my own hwnd */
+    HWND         hwndCombo;
+    HWND         hwndEdit;
+    WNDPROC      prevEditWndProc;  /* previous Edit WNDPROC value */
+    WNDPROC      prevComboWndProc; /* previous Combo WNDPROC value */
+    DWORD        dwExtStyle;
+    INT          selected;         /* index of selected item */
+    DWORD        flags;            /* WINE internal flags */
+    HFONT        defaultFont;
+    HFONT        font;
+    INT          nb_items;         /* Number of items */
+    BOOL         unicode;          /* TRUE if this window is Unicode   */
+    BOOL         NtfUnicode;       /* TRUE if parent wants notify in Unicode */
+    CBE_ITEMDATA *edit;            /* item data for edit item */
+    CBE_ITEMDATA *items;           /* Array of items */
+} COMBOEX_INFO;
+
+/* internal flags in the COMBOEX_INFO structure */
+#define  WCBE_ACTEDIT          0x00000001  /* Edit active i.e.
+                                             * CBEN_BEGINEDIT issued
+                                             * but CBEN_ENDEDIT{A|W}
+                                             * not yet issued. */
+#define  WCBE_EDITCHG          0x00000002  /* Edit issued EN_CHANGE */
+#define  WCBE_EDITHASCHANGED   (WCBE_ACTEDIT | WCBE_EDITCHG)
+#define  WCBE_EDITFOCUSED      0x00000004  /* Edit control has focus */
+#define  WCBE_MOUSECAPTURED    0x00000008  /* Combo has captured mouse */
+#define  WCBE_MOUSEDRAGGED      0x00000010  /* User has dragged in combo */
+
+#define ID_CB_EDIT             1001
+
+
+/*
+ * Special flag set in DRAWITEMSTRUCT itemState field. It is set by
+ * the ComboEx version of the Combo Window Proc so that when the
+ * WM_DRAWITEM message is then passed to ComboEx, we know that this
+ * particular WM_DRAWITEM message is for listbox only items. Any messasges
+ * without this flag is then for the Edit control field.
+ *
+ * We really cannot use the ODS_COMBOBOXEDIT flag because MSDN states that
+ * only version 4.0 applications will have ODS_COMBOBOXEDIT set.
+ */
+#define ODS_COMBOEXLBOX                0x4000
+
+
+
+/* Height in pixels of control over the amount of the selected font */
+#define CBE_EXTRA              3
+
+/* Indent amount per MS documentation */
+#define CBE_INDENT             10
+
+/* Offset in pixels from left side for start of image or text */
+#define CBE_STARTOFFSET                6
+
+/* Offset between image and text */
+#define CBE_SEP                        4
+
+#define COMBOEX_SUBCLASS_PROP  "CCComboEx32SubclassInfo"
+#define COMBOEX_GetInfoPtr(hwnd) ((COMBOEX_INFO *)GetWindowLongW (hwnd, 0))
+
+
+/* Things common to the entire DLL */
+static LRESULT WINAPI
+COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static LRESULT WINAPI
+COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static int CALLBACK
+COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code);
+static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr);
+typedef INT (WINAPI *cmp_func_t)(LPCWSTR, LPCWSTR);
+
+inline static BOOL is_textW(LPCWSTR str)
+{
+    return str && str != LPSTR_TEXTCALLBACKW;
+}
+
+inline static BOOL is_textA(LPCSTR str)
+{
+    return str && str != LPSTR_TEXTCALLBACKA;
+}
+
+inline static LPCSTR debugstr_txt(LPCWSTR str)
+{
+    if (str == LPSTR_TEXTCALLBACKW) return "(callback)";
+    return debugstr_w(str);
+}
+
+static void COMBOEX_DumpItem (CBE_ITEMDATA *item)
+{
+    TRACE("item %p - mask=%08x, pszText=%p, cchTM=%d, iImage=%d\n",
+          item, item->mask, item->pszText, item->cchTextMax, item->iImage);
+    TRACE("item %p - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
+          item, item->iSelectedImage, item->iOverlay, item->iIndent, item->lParam);
+    if (item->mask & CBEIF_TEXT)
+        TRACE("item %p - pszText=%s\n", item, debugstr_txt(item->pszText));
+}
+
+
+static void COMBOEX_DumpInput (COMBOBOXEXITEMW *input)
+{
+    TRACE("input - mask=%08x, iItem=%d, pszText=%p, cchTM=%d, iImage=%d\n",
+          input->mask, input->iItem, input->pszText, input->cchTextMax,
+          input->iImage);
+    if (input->mask & CBEIF_TEXT)
+        TRACE("input - pszText=<%s>\n", debugstr_txt(input->pszText));
+    TRACE("input - iSelectedImage=%d, iOverlay=%d, iIndent=%d, lParam=%08lx\n",
+          input->iSelectedImage, input->iOverlay, input->iIndent, input->lParam);
+}
+
+
+inline static CBE_ITEMDATA *get_item_data(COMBOEX_INFO *infoPtr, INT index)
+{
+    return (CBE_ITEMDATA *)SendMessageW (infoPtr->hwndCombo, CB_GETITEMDATA,
+                                        (WPARAM)index, 0);
+}
+
+inline static cmp_func_t get_cmp_func(COMBOEX_INFO *infoPtr)
+{
+    return infoPtr->dwExtStyle & CBES_EX_CASESENSITIVE ? lstrcmpW : lstrcmpiW;
+}
+
+static INT COMBOEX_Notify (COMBOEX_INFO *infoPtr, INT code, NMHDR *hdr)
+{
+    hdr->idFrom = GetDlgCtrlID (infoPtr->hwndSelf);
+    hdr->hwndFrom = infoPtr->hwndSelf;
+    hdr->code = code;
+    if (infoPtr->NtfUnicode)
+       return SendMessageW (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
+                            (LPARAM)hdr);
+    else
+       return SendMessageA (GetParent(infoPtr->hwndSelf), WM_NOTIFY, 0,
+                            (LPARAM)hdr);
+}
+
+
+static INT
+COMBOEX_NotifyItem (COMBOEX_INFO *infoPtr, INT code, NMCOMBOBOXEXW *hdr)
+{
+    /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */
+    if (infoPtr->NtfUnicode)
+       return COMBOEX_Notify (infoPtr, code, &hdr->hdr);
+    else {
+       LPWSTR wstr = hdr->ceItem.pszText;
+       LPSTR astr = 0;
+       INT ret, len = 0;
+
+       if ((hdr->ceItem.mask & CBEIF_TEXT) && is_textW(wstr)) {
+           len = WideCharToMultiByte (CP_ACP, 0, wstr, -1, 0, 0, NULL, NULL);
+           if (len > 0) {
+               astr = (LPSTR)Alloc ((len + 1)*sizeof(CHAR));
+               if (!astr) return 0;
+               WideCharToMultiByte (CP_ACP, 0, wstr, -1, astr, len, 0, 0);
+               hdr->ceItem.pszText = (LPWSTR)astr;
+           }
+       }
+
+       if (code == CBEN_ENDEDITW) code = CBEN_ENDEDITA;
+       else if (code == CBEN_GETDISPINFOW) code = CBEN_GETDISPINFOA;
+       else if (code == CBEN_DRAGBEGINW) code = CBEN_DRAGBEGINA;
+
+       ret = COMBOEX_Notify (infoPtr, code, (NMHDR *)hdr);
+
+       if (astr && hdr->ceItem.pszText == (LPWSTR)astr)
+           hdr->ceItem.pszText = wstr;
+
+       if (astr) Free(astr);
+
+       return ret;
+    }
+}
+
+
+static INT COMBOEX_NotifyEndEdit (COMBOEX_INFO *infoPtr, NMCBEENDEDITW *neew, LPCWSTR wstr)
+{
+    /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */
+    if (infoPtr->NtfUnicode) {
+       lstrcpynW(neew->szText, wstr, CBEMAXSTRLEN);
+       return COMBOEX_Notify (infoPtr, CBEN_ENDEDITW, &neew->hdr);
+    } else {
+       NMCBEENDEDITA neea;
+
+        memcpy (&neea.hdr, &neew->hdr, sizeof(NMHDR));
+        neea.fChanged = neew->fChanged;
+        neea.iNewSelection = neew->iNewSelection;
+        WideCharToMultiByte (CP_ACP, 0, wstr, -1, neea.szText, CBEMAXSTRLEN, 0, 0);
+        neea.iWhy = neew->iWhy;
+
+        return COMBOEX_Notify (infoPtr, CBEN_ENDEDITA, &neea.hdr);
+    }
+}
+
+
+static void COMBOEX_NotifyDragBegin(COMBOEX_INFO *infoPtr, LPCWSTR wstr)
+{
+    /* Change the Text item from Unicode to ANSI if necessary for NOTIFY */
+    if (infoPtr->NtfUnicode) {
+        NMCBEDRAGBEGINW ndbw;
+
+       ndbw.iItemid = -1;
+       lstrcpynW(ndbw.szText, wstr, CBEMAXSTRLEN);
+       COMBOEX_Notify (infoPtr, CBEN_DRAGBEGINW, &ndbw.hdr);
+    } else {
+       NMCBEDRAGBEGINA ndba;
+
+       ndba.iItemid = -1;
+       WideCharToMultiByte (CP_ACP, 0, wstr, -1, ndba.szText, CBEMAXSTRLEN, 0, 0);
+
+       COMBOEX_Notify (infoPtr, CBEN_DRAGBEGINA, &ndba.hdr);
+    }
+}
+
+
+static void COMBOEX_FreeText (CBE_ITEMDATA *item)
+{
+    if (is_textW(item->pszText)) Free(item->pszText);
+    item->pszText = 0;
+    if (item->pszTemp) Free(item->pszTemp);
+    item->pszTemp = 0;
+}
+
+
+static LPCWSTR COMBOEX_GetText(COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)
+{
+    NMCOMBOBOXEXW nmce;
+    LPWSTR text, buf;
+    INT len;
+
+    if (item->pszText != LPSTR_TEXTCALLBACKW)
+       return item->pszText;
+
+    ZeroMemory(&nmce, sizeof(nmce));
+    nmce.ceItem.mask = CBEIF_TEXT;
+    nmce.ceItem.lParam = item->lParam;
+    COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);
+
+    if (is_textW(nmce.ceItem.pszText)) {
+       len = MultiByteToWideChar (CP_ACP, 0, (LPSTR)nmce.ceItem.pszText, -1, NULL, 0);
+       buf = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+       if (buf)
+           MultiByteToWideChar (CP_ACP, 0, (LPSTR)nmce.ceItem.pszText, -1, buf, len);
+       if (nmce.ceItem.mask & CBEIF_DI_SETITEM) {
+           COMBOEX_FreeText(item);
+           item->pszText = buf;
+       } else {
+           if (item->pszTemp) Free(item->pszTemp);
+           item->pszTemp = buf;
+       }
+       text = buf;
+    } else
+       text = nmce.ceItem.pszText;
+
+    if (nmce.ceItem.mask & CBEIF_DI_SETITEM)
+       item->pszText = text;
+    return text;
+}
+
+
+static void COMBOEX_GetComboFontSize (COMBOEX_INFO *infoPtr, SIZE *size)
+{
+    HFONT nfont, ofont;
+    HDC mydc;
+
+    mydc = GetDC (0); /* why the entire screen???? */
+    nfont = (HFONT)SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
+    ofont = (HFONT) SelectObject (mydc, nfont);
+    GetTextExtentPointA (mydc, "A", 1, size);
+    SelectObject (mydc, ofont);
+    ReleaseDC (0, mydc);
+    TRACE("selected font hwnd=%p, height=%ld\n", nfont, size->cy);
+}
+
+
+static void COMBOEX_CopyItem (CBE_ITEMDATA *item, COMBOBOXEXITEMW *cit)
+{
+    if (cit->mask & CBEIF_TEXT) {
+        /*
+         * when given a text buffer actually use that buffer
+         */
+        if (cit->pszText) {
+           if (is_textW(item->pszText))
+                lstrcpynW(cit->pszText, item->pszText, cit->cchTextMax);
+           else
+               cit->pszText[0] = 0;
+        } else {
+            cit->pszText        = item->pszText;
+            cit->cchTextMax     = item->cchTextMax;
+        }
+    }
+    if (cit->mask & CBEIF_IMAGE)
+       cit->iImage         = item->iImage;
+    if (cit->mask & CBEIF_SELECTEDIMAGE)
+       cit->iSelectedImage = item->iSelectedImage;
+    if (cit->mask & CBEIF_OVERLAY)
+       cit->iOverlay       = item->iOverlay;
+    if (cit->mask & CBEIF_INDENT)
+       cit->iIndent        = item->iIndent;
+    if (cit->mask & CBEIF_LPARAM)
+       cit->lParam         = item->lParam;
+}
+
+
+static void COMBOEX_AdjustEditPos (COMBOEX_INFO *infoPtr)
+{
+    SIZE mysize;
+    INT x, y, w, h, xioff;
+    RECT rect;
+
+    if (!infoPtr->hwndEdit) return;
+
+    if (infoPtr->himl && !(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGEINDENT)) {
+       IMAGEINFO iinfo;
+        iinfo.rcImage.left = iinfo.rcImage.right = 0;
+       ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo);
+       xioff = iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP;
+    }  else xioff = 0;
+
+    GetClientRect (infoPtr->hwndCombo, &rect);
+    InflateRect (&rect, -2, -2);
+    InvalidateRect (infoPtr->hwndCombo, &rect, TRUE);
+
+    /* reposition the Edit control based on whether icon exists */
+    COMBOEX_GetComboFontSize (infoPtr, &mysize);
+    TRACE("Combo font x=%ld, y=%ld\n", mysize.cx, mysize.cy);
+    x = xioff + CBE_STARTOFFSET + 1;
+    w = rect.right-rect.left - x - GetSystemMetrics(SM_CXVSCROLL) - 1;
+    h = mysize.cy + 1;
+    y = rect.bottom - h - 1;
+
+    TRACE("Combo client (%ld,%ld)-(%ld,%ld), setting Edit to (%d,%d)-(%d,%d)\n",
+         rect.left, rect.top, rect.right, rect.bottom, x, y, x + w, y + h);
+    SetWindowPos(infoPtr->hwndEdit, HWND_TOP, x, y, w, h,
+                SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
+}
+
+
+static void COMBOEX_ReSize (COMBOEX_INFO *infoPtr)
+{
+    SIZE mysize;
+    UINT cy;
+    IMAGEINFO iinfo;
+
+    COMBOEX_GetComboFontSize (infoPtr, &mysize);
+    cy = mysize.cy + CBE_EXTRA;
+    if (infoPtr->himl && ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo)) {
+       cy = max (iinfo.rcImage.bottom - iinfo.rcImage.top, cy);
+       TRACE("upgraded height due to image:  height=%d\n", cy);
+    }
+    SendMessageW (infoPtr->hwndSelf, CB_SETITEMHEIGHT, (WPARAM)-1, (LPARAM)cy);
+    if (infoPtr->hwndCombo) {
+        SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
+                     (WPARAM) 0, (LPARAM) cy);
+       if ( !(infoPtr->flags & CBES_EX_NOSIZELIMIT)) {
+           RECT comboRect;
+           if (GetWindowRect(infoPtr->hwndCombo, &comboRect)) {
+               RECT ourRect;
+               if (GetWindowRect(infoPtr->hwndSelf, &ourRect)) {
+                   if (comboRect.bottom > ourRect.bottom) {
+                       POINT pt = { ourRect.left, ourRect.top };
+                       if (ScreenToClient(infoPtr->hwndSelf, &pt))
+                           MoveWindow( infoPtr->hwndSelf, pt.x, pt.y, ourRect.right - ourRect.left,
+                                       comboRect.bottom - comboRect.top, FALSE);
+                   }
+               }
+           }
+       }
+    }
+}
+
+
+static void COMBOEX_SetEditText (COMBOEX_INFO *infoPtr, CBE_ITEMDATA *item)
+{
+    if (!infoPtr->hwndEdit) return;
+    /* native issues the following messages to the {Edit} control */
+    /*      WM_SETTEXT (0,addr)     */
+    /*      EM_SETSEL32 (0,0)       */
+    /*      EM_SETSEL32 (0,-1)      */
+    if (item->mask & CBEIF_TEXT) {
+       SendMessageW (infoPtr->hwndEdit, WM_SETTEXT, 0, (LPARAM)COMBOEX_GetText(infoPtr, item));
+       SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
+       SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
+    }
+}
+
+
+static CBE_ITEMDATA * COMBOEX_FindItem(COMBOEX_INFO *infoPtr, INT index)
+{
+    CBE_ITEMDATA *item;
+    INT i;
+
+    if ((index > infoPtr->nb_items) || (index < -1))
+       return 0;
+    if (index == -1)
+       return infoPtr->edit;
+    item = infoPtr->items;
+    i = infoPtr->nb_items - 1;
+
+    /* find the item in the list */
+    while (item && (i > index)) {
+       item = (CBE_ITEMDATA *)item->next;
+       i--;
+    }
+    if (!item || (i != index)) {
+       ERR("COMBOBOXEX item structures broken. Please report!\n");
+       return 0;
+    }
+    return item;
+}
+
+
+static inline BOOL COMBOEX_HasEdit(COMBOEX_INFO *infoPtr)
+{
+    return infoPtr->hwndEdit ? TRUE : FALSE;
+}
+
+
+/* ***  CBEM_xxx message support  *** */
+
+
+static INT COMBOEX_DeleteItem (COMBOEX_INFO *infoPtr, INT index)
+{
+    CBE_ITEMDATA *item;
+
+    TRACE("(index=%d)\n", index);
+
+    /* if item number requested does not exist then return failure */
+    if ((index > infoPtr->nb_items) || (index < 0)) return CB_ERR;
+    if (!(item = COMBOEX_FindItem(infoPtr, index))) return CB_ERR;
+
+    /* doing this will result in WM_DELETEITEM being issued */
+    SendMessageW (infoPtr->hwndCombo, CB_DELETESTRING, (WPARAM)index, 0);
+
+    return infoPtr->nb_items;
+}
+
+
+static BOOL COMBOEX_GetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
+{
+    INT index = cit->iItem;
+    CBE_ITEMDATA *item;
+
+    TRACE("(...)\n");
+
+    /* if item number requested does not exist then return failure */
+    if ((index > infoPtr->nb_items) || (index < -1)) return FALSE;
+
+    /* if the item is the edit control and there is no edit control, skip */
+    if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;
+
+    if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;
+
+    COMBOEX_CopyItem (item, cit);
+
+    return TRUE;
+}
+
+
+static BOOL COMBOEX_GetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
+{
+    COMBOBOXEXITEMW tmpcit;
+
+    TRACE("(...)\n");
+
+    tmpcit.mask = cit->mask;
+    tmpcit.iItem = cit->iItem;
+    tmpcit.pszText = 0;
+    if(!COMBOEX_GetItemW (infoPtr, &tmpcit)) return FALSE;
+
+    if (is_textW(tmpcit.pszText) && cit->pszText)
+        WideCharToMultiByte (CP_ACP, 0, tmpcit.pszText, -1,
+                            cit->pszText, cit->cchTextMax, NULL, NULL);
+    else if (cit->pszText) cit->pszText[0] = 0;
+    else cit->pszText = (LPSTR)tmpcit.pszText;
+
+    cit->iImage = tmpcit.iImage;
+    cit->iSelectedImage = tmpcit.iSelectedImage;
+    cit->iOverlay = tmpcit.iOverlay;
+    cit->iIndent = tmpcit.iIndent;
+    cit->lParam = tmpcit.lParam;
+
+    return TRUE;
+}
+
+
+inline static BOOL COMBOEX_HasEditChanged (COMBOEX_INFO *infoPtr)
+{
+    return COMBOEX_HasEdit(infoPtr) &&
+          (infoPtr->flags & WCBE_EDITHASCHANGED) == WCBE_EDITHASCHANGED;
+}
+
+
+static INT COMBOEX_InsertItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
+{
+    INT index;
+    CBE_ITEMDATA *item;
+    NMCOMBOBOXEXW nmcit;
+
+    TRACE("\n");
+
+    if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);
+
+    /* get real index of item to insert */
+    index = cit->iItem;
+    if (index == -1) index = infoPtr->nb_items;
+    if (index > infoPtr->nb_items) index = infoPtr->nb_items;
+
+    /* get zero-filled space and chain it in */
+    if(!(item = (CBE_ITEMDATA *)Alloc (sizeof(*item)))) return -1;
+
+    /* locate position to insert new item in */
+    if (index == infoPtr->nb_items) {
+        /* fast path for iItem = -1 */
+        item->next = infoPtr->items;
+       infoPtr->items = item;
+    }
+    else {
+        INT i = infoPtr->nb_items-1;
+       CBE_ITEMDATA *moving = infoPtr->items;
+
+       while ((i > index) && moving) {
+           moving = (CBE_ITEMDATA *)moving->next;
+           i--;
+       }
+       if (!moving) {
+           ERR("COMBOBOXEX item structures broken. Please report!\n");
+           Free(item);
+           return -1;
+       }
+       item->next = moving->next;
+       moving->next = item;
+    }
+
+    /* fill in our hidden item structure */
+    item->mask = cit->mask;
+    if (item->mask & CBEIF_TEXT) {
+       INT len = 0;
+
+        if (is_textW(cit->pszText)) len = strlenW (cit->pszText);
+       if (len > 0) {
+           item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+           if (!item->pszText) {
+               Free(item);
+               return -1;
+           }
+           strcpyW (item->pszText, cit->pszText);
+       }
+       else if (cit->pszText == LPSTR_TEXTCALLBACKW)
+           item->pszText = LPSTR_TEXTCALLBACKW;
+        item->cchTextMax = cit->cchTextMax;
+    }
+    if (item->mask & CBEIF_IMAGE)
+        item->iImage = cit->iImage;
+    if (item->mask & CBEIF_SELECTEDIMAGE)
+        item->iSelectedImage = cit->iSelectedImage;
+    if (item->mask & CBEIF_OVERLAY)
+        item->iOverlay = cit->iOverlay;
+    if (item->mask & CBEIF_INDENT)
+        item->iIndent = cit->iIndent;
+    if (item->mask & CBEIF_LPARAM)
+        item->lParam = cit->lParam;
+    infoPtr->nb_items++;
+
+    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
+
+    SendMessageW (infoPtr->hwndCombo, CB_INSERTSTRING,
+                 (WPARAM)cit->iItem, (LPARAM)item);
+
+    memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));
+    COMBOEX_CopyItem (item, &nmcit.ceItem);
+    COMBOEX_NotifyItem (infoPtr, CBEN_INSERTITEM, &nmcit);
+
+    return index;
+
+}
+
+
+static INT COMBOEX_InsertItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
+{
+    COMBOBOXEXITEMW citW;
+    LPWSTR wstr = NULL;
+    INT        ret;
+
+    memcpy(&citW,cit,sizeof(COMBOBOXEXITEMA));
+    if (cit->mask & CBEIF_TEXT && is_textA(cit->pszText)) {
+       INT len = MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, NULL, 0);
+       wstr = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+       if (!wstr) return -1;
+       MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, wstr, len);
+       citW.pszText = wstr;
+    }
+    ret = COMBOEX_InsertItemW(infoPtr, &citW);
+
+    if (wstr) Free(wstr);
+
+    return ret;
+}
+
+
+static DWORD
+COMBOEX_SetExtendedStyle (COMBOEX_INFO *infoPtr, DWORD mask, DWORD style)
+{
+    DWORD dwTemp;
+
+    TRACE("(mask=x%08lx, style=0x%08lx)\n", mask, style);
+
+    dwTemp = infoPtr->dwExtStyle;
+
+    if (mask)
+       infoPtr->dwExtStyle = (infoPtr->dwExtStyle & ~mask) | style;
+    else
+       infoPtr->dwExtStyle = style;
+
+    /* see if we need to change the word break proc on the edit */
+    if ((infoPtr->dwExtStyle ^ dwTemp) & CBES_EX_PATHWORDBREAKPROC) {
+       SendMessageW(infoPtr->hwndEdit, EM_SETWORDBREAKPROC, 0,
+                    (infoPtr->dwExtStyle & CBES_EX_PATHWORDBREAKPROC) ?
+                        (LPARAM)COMBOEX_PathWordBreakProc : 0);
+    }
+
+    /* test if the control's appearance has changed */
+    mask = CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT;
+    if ((infoPtr->dwExtStyle & mask) != (dwTemp & mask)) {
+       /* if state of EX_NOEDITIMAGE changes, invalidate all */
+       TRACE("EX_NOEDITIMAGE state changed to %ld\n",
+             infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGE);
+       InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
+       COMBOEX_AdjustEditPos (infoPtr);
+       if (infoPtr->hwndEdit)
+           InvalidateRect (infoPtr->hwndEdit, NULL, TRUE);
+    }
+
+    return dwTemp;
+}
+
+
+static HIMAGELIST COMBOEX_SetImageList (COMBOEX_INFO *infoPtr, HIMAGELIST himl)
+{
+    HIMAGELIST himlTemp = infoPtr->himl;
+
+    TRACE("(...)\n");
+
+    infoPtr->himl = himl;
+
+    COMBOEX_ReSize (infoPtr);
+    InvalidateRect (infoPtr->hwndCombo, NULL, TRUE);
+
+    /* reposition the Edit control based on whether icon exists */
+    COMBOEX_AdjustEditPos (infoPtr);
+    return himlTemp;
+}
+
+static BOOL COMBOEX_SetItemW (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMW *cit)
+{
+    INT index = cit->iItem;
+    CBE_ITEMDATA *item;
+
+    if (TRACE_ON(comboex)) COMBOEX_DumpInput (cit);
+
+    /* if item number requested does not exist then return failure */
+    if ((index > infoPtr->nb_items) || (index < -1)) return FALSE;
+
+    /* if the item is the edit control and there is no edit control, skip */
+    if ((index == -1) && !COMBOEX_HasEdit(infoPtr)) return FALSE;
+
+    if (!(item = COMBOEX_FindItem(infoPtr, index))) return FALSE;
+
+    /* add/change stuff to the internal item structure */
+    item->mask |= cit->mask;
+    if (cit->mask & CBEIF_TEXT) {
+       INT len = 0;
+
+       COMBOEX_FreeText(item);
+        if (is_textW(cit->pszText)) len = strlenW(cit->pszText);
+       if (len > 0) {
+           item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+           if (!item->pszText) return FALSE;
+           strcpyW(item->pszText, cit->pszText);
+       } else if (cit->pszText == LPSTR_TEXTCALLBACKW)
+           item->pszText = LPSTR_TEXTCALLBACKW;
+        item->cchTextMax = cit->cchTextMax;
+    }
+    if (cit->mask & CBEIF_IMAGE)
+        item->iImage = cit->iImage;
+    if (cit->mask & CBEIF_SELECTEDIMAGE)
+        item->iSelectedImage = cit->iSelectedImage;
+    if (cit->mask & CBEIF_OVERLAY)
+        item->iOverlay = cit->iOverlay;
+    if (cit->mask & CBEIF_INDENT)
+        item->iIndent = cit->iIndent;
+    if (cit->mask & CBEIF_LPARAM)
+        cit->lParam = cit->lParam;
+
+    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
+
+    /* if original request was to update edit control, do some fast foot work */
+    if (cit->iItem == -1) {
+       COMBOEX_SetEditText (infoPtr, item);
+       RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE | RDW_INVALIDATE);
+    }
+    return TRUE;
+}
+
+static BOOL COMBOEX_SetItemA (COMBOEX_INFO *infoPtr, COMBOBOXEXITEMA *cit)
+{
+    COMBOBOXEXITEMW citW;
+    LPWSTR wstr = NULL;
+    BOOL ret;
+
+    memcpy(&citW, cit, sizeof(COMBOBOXEXITEMA));
+    if ((cit->mask & CBEIF_TEXT) && is_textA(cit->pszText)) {
+       INT len = MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, NULL, 0);
+       wstr = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+       if (!wstr) return FALSE;
+       MultiByteToWideChar (CP_ACP, 0, cit->pszText, -1, wstr, len);
+       citW.pszText = wstr;
+    }
+    ret = COMBOEX_SetItemW(infoPtr, &citW);
+
+    if (wstr) Free(wstr);
+
+    return ret;
+}
+
+
+static BOOL COMBOEX_SetUnicodeFormat (COMBOEX_INFO *infoPtr, BOOL value)
+{
+    BOOL bTemp = infoPtr->unicode;
+
+    TRACE("to %s, was %s\n", value ? "TRUE":"FALSE", bTemp ? "TRUE":"FALSE");
+
+    infoPtr->unicode = value;
+
+    return bTemp;
+}
+
+
+/* ***  CB_xxx message support  *** */
+
+static INT
+COMBOEX_FindStringExact (COMBOEX_INFO *infoPtr, INT start, LPCWSTR str)
+{
+    INT i;
+    cmp_func_t cmptext = get_cmp_func(infoPtr);
+    INT count = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0);
+
+    /* now search from after starting loc and wrapping back to start */
+    for(i=start+1; i<count; i++) {
+       CBE_ITEMDATA *item = get_item_data(infoPtr, i);
+       if (cmptext(COMBOEX_GetText(infoPtr, item), str) == 0) return i;
+    }
+    for(i=0; i<=start; i++) {
+       CBE_ITEMDATA *item = get_item_data(infoPtr, i);
+       if (cmptext(COMBOEX_GetText(infoPtr, item), str) == 0) return i;
+    }
+    return CB_ERR;
+}
+
+
+static DWORD COMBOEX_GetItemData (COMBOEX_INFO *infoPtr, INT index)
+{
+    CBE_ITEMDATA *item1, *item2;
+    DWORD ret = 0;
+
+    item1 = get_item_data(infoPtr, index);
+    if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) {
+       item2 = COMBOEX_FindItem (infoPtr, index);
+       if (item2 != item1) {
+           ERR("data structures damaged!\n");
+           return CB_ERR;
+       }
+       if (item1->mask & CBEIF_LPARAM) ret = item1->lParam;
+       TRACE("returning 0x%08lx\n", ret);
+    } else {
+        ret = (DWORD)item1;
+        TRACE("non-valid result from combo, returning 0x%08lx\n", ret);
+    }
+    return ret;
+}
+
+
+static INT COMBOEX_SetCursel (COMBOEX_INFO *infoPtr, INT index)
+{
+    CBE_ITEMDATA *item;
+    INT sel;
+
+    if (!(item = COMBOEX_FindItem(infoPtr, index)))
+       return SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, index, 0);
+
+    TRACE("selecting item %d text=%s\n", index, debugstr_txt(item->pszText));
+    infoPtr->selected = index;
+
+    sel = (INT)SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL, index, 0);
+    COMBOEX_SetEditText (infoPtr, item);
+    return sel;
+}
+
+
+static DWORD COMBOEX_SetItemData (COMBOEX_INFO *infoPtr, INT index, DWORD data)
+{
+    CBE_ITEMDATA *item1, *item2;
+
+    item1 = get_item_data(infoPtr, index);
+    if ((item1 != NULL) && ((LRESULT)item1 != CB_ERR)) {
+       item2 = COMBOEX_FindItem (infoPtr, index);
+       if (item2 != item1) {
+           ERR("data structures damaged!\n");
+           return CB_ERR;
+       }
+       item1->mask |= CBEIF_LPARAM;
+       item1->lParam = data;
+       TRACE("setting lparam to 0x%08lx\n", data);
+       return 0;
+    }
+    TRACE("non-valid result from combo 0x%08lx\n", (DWORD)item1);
+    return (LRESULT)item1;
+}
+
+
+static INT COMBOEX_SetItemHeight (COMBOEX_INFO *infoPtr, INT index, UINT height)
+{
+    RECT cb_wrect, cbx_wrect, cbx_crect;
+
+    /* First, lets forward the message to the normal combo control
+       just like Windows.     */
+    if (infoPtr->hwndCombo)
+       if (SendMessageW (infoPtr->hwndCombo, CB_SETITEMHEIGHT,
+                        index, height) == CB_ERR) return CB_ERR;
+
+    GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
+    GetWindowRect (infoPtr->hwndSelf, &cbx_wrect);
+    GetClientRect (infoPtr->hwndSelf, &cbx_crect);
+    /* the height of comboex as height of the combo + comboex border */
+    height = cb_wrect.bottom-cb_wrect.top
+             + cbx_wrect.bottom-cbx_wrect.top
+             - (cbx_crect.bottom-cbx_crect.top);
+    TRACE("EX window=(%ld,%ld)-(%ld,%ld), client=(%ld,%ld)-(%ld,%ld)\n",
+         cbx_wrect.left, cbx_wrect.top, cbx_wrect.right, cbx_wrect.bottom,
+         cbx_crect.left, cbx_crect.top, cbx_crect.right, cbx_crect.bottom);
+    TRACE("CB window=(%ld,%ld)-(%ld,%ld), EX setting=(0,0)-(%ld,%d)\n",
+         cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom,
+         cbx_wrect.right-cbx_wrect.left, height);
+    SetWindowPos (infoPtr->hwndSelf, HWND_TOP, 0, 0,
+                 cbx_wrect.right-cbx_wrect.left, height,
+                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
+
+    return 0;
+}
+
+
+/* ***  WM_xxx message support  *** */
+
+
+static LRESULT COMBOEX_Create (HWND hwnd, LPCREATESTRUCTA cs)
+{
+    WCHAR COMBOBOX[] = { 'C', 'o', 'm', 'b', 'o', 'B', 'o', 'x', 0 };
+    WCHAR EDIT[] = { 'E', 'D', 'I', 'T', 0 };
+    WCHAR NIL[] = { 0 };
+    COMBOEX_INFO *infoPtr;
+    LOGFONTW mylogfont;
+    RECT wnrc1, clrc1, cmbwrc;
+    INT i;
+
+    /* allocate memory for info structure */
+    infoPtr = (COMBOEX_INFO *)Alloc (sizeof(COMBOEX_INFO));
+    if (!infoPtr) return -1;
+
+    /* initialize info structure */
+    /* note that infoPtr is allocated zero-filled */
+
+    infoPtr->hwndSelf = hwnd;
+    infoPtr->selected = -1;
+
+    infoPtr->unicode = IsWindowUnicode (hwnd);
+
+    i = SendMessageW(GetParent (hwnd), WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
+    if ((i != NFR_ANSI) && (i != NFR_UNICODE)) {
+       WARN("wrong response to WM_NOTIFYFORMAT (%d), assuming ANSI\n", i);
+       i = NFR_ANSI;
+    }
+    infoPtr->NtfUnicode = (i == NFR_UNICODE);
+
+    SetWindowLongW (hwnd, 0, (DWORD)infoPtr);
+
+    /* create combo box */
+    GetWindowRect(hwnd, &wnrc1);
+    GetClientRect(hwnd, &clrc1);
+    TRACE("EX window=(%ld,%ld)-(%ld,%ld) client=(%ld,%ld)-(%ld,%ld)\n",
+         wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom,
+         clrc1.left, clrc1.top, clrc1.right, clrc1.bottom);
+
+    /* Native version of ComboEx creates the ComboBox with DROPDOWNLIST */
+    /* specified. It then creates it's own version of the EDIT control  */
+    /* and makes the ComboBox the parent. This is because a normal      */
+    /* DROPDOWNLIST does not have a EDIT control, but we need one.      */
+    /* We also need to place the edit control at the proper location    */
+    /* (allow space for the icons).                                     */
+
+    infoPtr->hwndCombo = CreateWindowW (COMBOBOX, NIL,
+                        /* following line added to match native */
+                         WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VSCROLL |
+                         CBS_NOINTEGRALHEIGHT | CBS_DROPDOWNLIST |
+                        /* was base and is necessary */
+                        WS_CHILD | WS_VISIBLE | CBS_OWNERDRAWFIXED |
+                        GetWindowLongW (hwnd, GWL_STYLE),
+                        cs->y, cs->x, cs->cx, cs->cy, hwnd,
+                        (HMENU) GetWindowLongW (hwnd, GWL_ID),
+                        (HINSTANCE)GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);
+
+    /*
+     * native does the following at this point according to trace:
+     *  GetWindowThreadProcessId(hwndCombo,0)
+     *  GetCurrentThreadId()
+     *  GetWindowThreadProcessId(hwndCombo, &???)
+     *  GetCurrentProcessId()
+     */
+
+    /*
+     * Setup a property to hold the pointer to the COMBOBOXEX
+     * data structure.
+     */
+    SetPropA(infoPtr->hwndCombo, COMBOEX_SUBCLASS_PROP, hwnd);
+    infoPtr->prevComboWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndCombo,
+                               GWL_WNDPROC, (LONG)COMBOEX_ComboWndProc);
+    infoPtr->font = (HFONT)SendMessageW (infoPtr->hwndCombo, WM_GETFONT, 0, 0);
+
+
+    /*
+     * Now create our own EDIT control so we can position it.
+     * It is created only for CBS_DROPDOWN style
+     */
+    if ((cs->style & CBS_DROPDOWNLIST) == CBS_DROPDOWN) {
+       infoPtr->hwndEdit = CreateWindowExW (0, EDIT, NIL,
+                   WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | ES_AUTOHSCROLL,
+                   0, 0, 0, 0,  /* will set later */
+                   infoPtr->hwndCombo,
+                   (HMENU) GetWindowLongW (hwnd, GWL_ID),
+                   (HINSTANCE)GetWindowLongW (hwnd, GWL_HINSTANCE), NULL);
+
+       /* native does the following at this point according to trace:
+        *  GetWindowThreadProcessId(hwndEdit,0)
+        *  GetCurrentThreadId()
+        *  GetWindowThreadProcessId(hwndEdit, &???)
+        *  GetCurrentProcessId()
+        */
+
+       /*
+        * Setup a property to hold the pointer to the COMBOBOXEX
+        * data structure.
+        */
+        SetPropA(infoPtr->hwndEdit, COMBOEX_SUBCLASS_PROP, hwnd);
+       infoPtr->prevEditWndProc = (WNDPROC)SetWindowLongW(infoPtr->hwndEdit,
+                                GWL_WNDPROC, (LONG)COMBOEX_EditWndProc);
+       infoPtr->font = (HFONT)SendMessageW(infoPtr->hwndCombo, WM_GETFONT, 0, 0);
+    }
+
+    /*
+     * Locate the default font if necessary and then set it in
+     * all associated controls
+     */
+    if (!infoPtr->font) {
+       SystemParametersInfoW (SPI_GETICONTITLELOGFONT, sizeof(mylogfont),
+                              &mylogfont, 0);
+       infoPtr->font = infoPtr->defaultFont = CreateFontIndirectW (&mylogfont);
+    }
+    SendMessageW (infoPtr->hwndCombo, WM_SETFONT, (WPARAM)infoPtr->font, 0);
+    if (infoPtr->hwndEdit) {
+       SendMessageW (infoPtr->hwndEdit, WM_SETFONT, (WPARAM)infoPtr->font, 0);
+       SendMessageW (infoPtr->hwndEdit, EM_SETMARGINS, (WPARAM)EC_USEFONTINFO, 0);
+    }
+
+    COMBOEX_ReSize (infoPtr);
+
+    /* Above is fairly certain, below is much less certain. */
+
+    GetWindowRect(hwnd, &wnrc1);
+    GetClientRect(hwnd, &clrc1);
+    GetWindowRect(infoPtr->hwndCombo, &cmbwrc);
+    TRACE("EX window=(%ld,%ld)-(%ld,%ld) client=(%ld,%ld)-(%ld,%ld) CB wnd=(%ld,%ld)-(%ld,%ld)\n",
+         wnrc1.left, wnrc1.top, wnrc1.right, wnrc1.bottom,
+         clrc1.left, clrc1.top, clrc1.right, clrc1.bottom,
+         cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom);
+    SetWindowPos(infoPtr->hwndCombo, HWND_TOP,
+                0, 0, wnrc1.right-wnrc1.left, wnrc1.bottom-wnrc1.top,
+                SWP_NOACTIVATE | SWP_NOREDRAW);
+
+    GetWindowRect(infoPtr->hwndCombo, &cmbwrc);
+    TRACE("CB window=(%ld,%ld)-(%ld,%ld)\n",
+         cmbwrc.left, cmbwrc.top, cmbwrc.right, cmbwrc.bottom);
+    SetWindowPos(hwnd, HWND_TOP,
+                0, 0, cmbwrc.right-cmbwrc.left, cmbwrc.bottom-cmbwrc.top,
+                SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
+
+    COMBOEX_AdjustEditPos (infoPtr);
+
+    /*
+     * Create an item structure to represent the data in the
+     * EDIT control. It is allocated zero-filled.
+     */
+    infoPtr->edit = (CBE_ITEMDATA *)Alloc (sizeof (CBE_ITEMDATA));
+    if (!infoPtr->edit) {
+       COMBOEX_Destroy(infoPtr);
+       return -1;
+    }
+
+    return 0;
+}
+
+
+static LRESULT COMBOEX_Command (COMBOEX_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+{
+    LRESULT lret;
+    INT command = HIWORD(wParam);
+    CBE_ITEMDATA *item = 0;
+    WCHAR wintext[520];
+    INT cursel, n, oldItem;
+    NMCBEENDEDITW cbeend;
+    DWORD oldflags;
+    HWND parent = GetParent (infoPtr->hwndSelf);
+
+    TRACE("for command %d\n", command);
+
+    switch (command)
+    {
+    case CBN_DROPDOWN:
+       SetFocus (infoPtr->hwndCombo);
+       ShowWindow (infoPtr->hwndEdit, SW_HIDE);
+       return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+
+    case CBN_CLOSEUP:
+       SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+       /*
+        * from native trace of first dropdown after typing in URL in IE4
+        *  CB_GETCURSEL(Combo)
+        *  GetWindowText(Edit)
+        *  CB_GETCURSEL(Combo)
+        *  CB_GETCOUNT(Combo)
+        *  CB_GETITEMDATA(Combo, n)
+        *  WM_NOTIFY(parent, CBEN_ENDEDITA|W)
+        *  CB_GETCURSEL(Combo)
+        *  CB_SETCURSEL(COMBOEX, n)
+        *  SetFocus(Combo)
+        * the rest is supposition
+        */
+       ShowWindow (infoPtr->hwndEdit, SW_SHOW);
+       InvalidateRect (infoPtr->hwndCombo, 0, TRUE);
+       InvalidateRect (infoPtr->hwndEdit, 0, TRUE);
+       cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
+       if (cursel == -1) {
+            cmp_func_t cmptext = get_cmp_func(infoPtr);
+           /* find match from edit against those in Combobox */
+           GetWindowTextW (infoPtr->hwndEdit, wintext, 520);
+           n = SendMessageW (infoPtr->hwndCombo, CB_GETCOUNT, 0, 0);
+           for (cursel = 0; cursel < n; cursel++){
+                item = get_item_data(infoPtr, cursel);
+               if ((INT)item == CB_ERR) break;
+               if (!cmptext(COMBOEX_GetText(infoPtr, item), wintext)) break;
+           }
+           if ((cursel == n) || ((INT)item == CB_ERR)) {
+               TRACE("failed to find match??? item=%p cursel=%d\n",
+                     item, cursel);
+               if (infoPtr->hwndEdit)
+                   SetFocus(infoPtr->hwndEdit);
+               return 0;
+           }
+       }
+       else {
+            item = get_item_data(infoPtr, cursel);
+           if ((INT)item == CB_ERR) {
+               TRACE("failed to find match??? item=%p cursel=%d\n",
+                     item, cursel);
+               if (infoPtr->hwndEdit)
+                   SetFocus(infoPtr->hwndEdit);
+               return 0;
+           }
+       }
+
+       /* Save flags for testing and reset them */
+       oldflags = infoPtr->flags;
+       infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
+
+       if (oldflags & WCBE_ACTEDIT) {
+           cbeend.fChanged = (oldflags & WCBE_EDITCHG);
+           cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
+                                                CB_GETCURSEL, 0, 0);
+           cbeend.iWhy = CBENF_DROPDOWN;
+
+           if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, COMBOEX_GetText(infoPtr, item))) return 0;
+       }
+
+       /* if selection has changed the set the new current selection */
+       cursel = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
+       if ((oldflags & WCBE_EDITCHG) || (cursel != infoPtr->selected)) {
+           infoPtr->selected = cursel;
+           SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, cursel, 0);
+           SetFocus(infoPtr->hwndCombo);
+       }
+       return 0;
+
+    case CBN_SELCHANGE:
+       /*
+        * CB_GETCURSEL(Combo)
+        * CB_GETITEMDATA(Combo)   < simulated by COMBOEX_FindItem
+        * lstrlenA
+        * WM_SETTEXT(Edit)
+        * WM_GETTEXTLENGTH(Edit)
+        * WM_GETTEXT(Edit)
+        * EM_SETSEL(Edit, 0,0)
+        * WM_GETTEXTLENGTH(Edit)
+        * WM_GETTEXT(Edit)
+        * EM_SETSEL(Edit, 0,len)
+        * return WM_COMMAND to parent
+        */
+       oldItem = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
+       if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) {
+           ERR("item %d not found. Problem!\n", oldItem);
+           break;
+       }
+       infoPtr->selected = oldItem;
+       COMBOEX_SetEditText (infoPtr, item);
+       return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+
+    case CBN_SELENDOK:
+       /*
+        * We have to change the handle since we are the control
+        * issuing the message. IE4 depends on this.
+        */
+       return SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+
+    case CBN_KILLFOCUS:
+       /*
+        * from native trace:
+        *
+        *  pass to parent
+        *  WM_GETTEXT(Edit, 104)
+        *  CB_GETCURSEL(Combo) rets -1
+        *  WM_NOTIFY(CBEN_ENDEDITA) with CBENF_KILLFOCUS
+        *  CB_GETCURSEL(Combo)
+        *  InvalidateRect(Combo, 0, 0)
+        *  return 0
+        */
+       SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+       if (infoPtr->flags & WCBE_ACTEDIT) {
+           GetWindowTextW (infoPtr->hwndEdit, wintext, 260);
+           cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
+           cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
+                                                CB_GETCURSEL, 0, 0);
+           cbeend.iWhy = CBENF_KILLFOCUS;
+
+           infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
+           if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, wintext)) return 0;
+       }
+       /* possible CB_GETCURSEL */
+       InvalidateRect (infoPtr->hwndCombo, 0, 0);
+       return 0;
+
+    default:
+       /*
+        * We have to change the handle since we are the control
+        * issuing the message. IE4 depends on this.
+        * We also need to set the focus back to the Edit control
+        * after passing the command to the parent of the ComboEx.
+        */
+       lret = SendMessageW (parent, WM_COMMAND, wParam, (LPARAM)infoPtr->hwndSelf);
+       if (infoPtr->hwndEdit)
+           SetFocus(infoPtr->hwndEdit);
+       return lret;
+    }
+    return 0;
+}
+
+
+static BOOL COMBOEX_WM_DeleteItem (COMBOEX_INFO *infoPtr, DELETEITEMSTRUCT *dis)
+{
+    CBE_ITEMDATA *item, *olditem;
+    NMCOMBOBOXEXW nmcit;
+    UINT i;
+
+    TRACE("CtlType=%08x, CtlID=%08x, itemID=%08x, hwnd=%p, data=%08lx\n",
+         dis->CtlType, dis->CtlID, dis->itemID, dis->hwndItem, dis->itemData);
+
+    if (dis->itemID >= infoPtr->nb_items) return FALSE;
+
+    olditem = infoPtr->items;
+    i = infoPtr->nb_items - 1;
+
+    if (i == dis->itemID) {
+       infoPtr->items = infoPtr->items->next;
+    }
+    else {
+       item = olditem;
+       i--;
+
+       /* find the prior item in the list */
+       while (item->next && (i > dis->itemID)) {
+           item = (CBE_ITEMDATA *)item->next;
+           i--;
+       }
+       if (!item->next || (i != dis->itemID)) {
+           ERR("COMBOBOXEX item structures broken. Please report!\n");
+           return FALSE;
+       }
+       olditem = item->next;
+       item->next = (CBE_ITEMDATA *)((CBE_ITEMDATA *)item->next)->next;
+    }
+    infoPtr->nb_items--;
+
+    memset (&nmcit.ceItem, 0, sizeof(nmcit.ceItem));
+    COMBOEX_CopyItem (olditem, &nmcit.ceItem);
+    COMBOEX_NotifyItem (infoPtr, CBEN_DELETEITEM, &nmcit);
+
+    COMBOEX_FreeText(olditem);
+    Free(olditem);
+
+    return TRUE;
+}
+
+
+static LRESULT COMBOEX_DrawItem (COMBOEX_INFO *infoPtr, DRAWITEMSTRUCT *dis)
+{
+    WCHAR nil[] = { 0 };
+    CBE_ITEMDATA *item = 0;
+    SIZE txtsize;
+    RECT rect;
+    LPCWSTR str = nil;
+    UINT xbase, x, y;
+    INT len;
+    COLORREF nbkc, ntxc, bkc, txc;
+    int drawimage, drawstate, xioff;
+
+    if (!IsWindowEnabled(infoPtr->hwndCombo)) return 0;
+
+    TRACE("DRAWITEMSTRUCT: CtlType=0x%08x CtlID=0x%08x\n",
+         dis->CtlType, dis->CtlID);
+    TRACE("itemID=0x%08x itemAction=0x%08x itemState=0x%08x\n",
+         dis->itemID, dis->itemAction, dis->itemState);
+    TRACE("hWnd=%p hDC=%p (%ld,%ld)-(%ld,%ld) itemData=0x%08lx\n",
+         dis->hwndItem, dis->hDC, dis->rcItem.left,
+         dis->rcItem.top, dis->rcItem.right, dis->rcItem.bottom,
+         dis->itemData);
+
+    /* MSDN says:                                                       */
+    /*     "itemID - Specifies the menu item identifier for a menu      */
+    /*      item or the index of the item in a list box or combo box.   */
+    /*      For an empty list box or combo box, this member can be -1.  */
+    /*      This allows the application to draw only the focus          */
+    /*      rectangle at the coordinates specified by the rcItem        */
+    /*      member even though there are no items in the control.       */
+    /*      This indicates to the user whether the list box or combo    */
+    /*      box has the focus. How the bits are set in the itemAction   */
+    /*      member determines whether the rectangle is to be drawn as   */
+    /*      though the list box or combo box has the focus.             */
+    if (dis->itemID == 0xffffffff) {
+       if ( ( (dis->itemAction & ODA_FOCUS) && (dis->itemState & ODS_SELECTED)) ||
+            ( (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) && (dis->itemState & ODS_FOCUS) ) ) {
+
+           TRACE("drawing item -1 special focus, rect=(%ld,%ld)-(%ld,%ld)\n",
+                 dis->rcItem.left, dis->rcItem.top,
+                 dis->rcItem.right, dis->rcItem.bottom);
+       }
+       else if ((dis->CtlType == ODT_COMBOBOX) &&
+                (dis->itemAction == ODA_DRAWENTIRE)) {
+           /* draw of edit control data */
+
+           /* testing */
+           {
+               RECT exrc, cbrc, edrc;
+               GetWindowRect (infoPtr->hwndSelf, &exrc);
+               GetWindowRect (infoPtr->hwndCombo, &cbrc);
+               edrc.left=edrc.top=edrc.right=edrc.bottom=-1;
+               if (infoPtr->hwndEdit)
+                   GetWindowRect (infoPtr->hwndEdit, &edrc);
+               TRACE("window rects ex=(%ld,%ld)-(%ld,%ld), cb=(%ld,%ld)-(%ld,%ld), ed=(%ld,%ld)-(%ld,%ld)\n",
+                     exrc.left, exrc.top, exrc.right, exrc.bottom,
+                     cbrc.left, cbrc.top, cbrc.right, cbrc.bottom,
+                     edrc.left, edrc.top, edrc.right, edrc.bottom);
+           }
+       }
+       else {
+           ERR("NOT drawing item  -1 special focus, rect=(%ld,%ld)-(%ld,%ld), action=%08x, state=%08x\n",
+               dis->rcItem.left, dis->rcItem.top,
+               dis->rcItem.right, dis->rcItem.bottom,
+               dis->itemAction, dis->itemState);
+           return 0;
+       }
+    }
+
+    /* If draw item is -1 (edit control) setup the item pointer */
+    if (dis->itemID == 0xffffffff) {
+       item = infoPtr->edit;
+
+       if (infoPtr->hwndEdit) {
+           INT len;
+
+           /* free previous text of edit item */
+           COMBOEX_FreeText(item);
+           item->mask &= ~CBEIF_TEXT;
+           if( (len = GetWindowTextLengthW(infoPtr->hwndEdit)) ) {
+               item->mask |= CBEIF_TEXT;
+               item->pszText = (LPWSTR)Alloc ((len + 1)*sizeof(WCHAR));
+               if (item->pszText)
+                   GetWindowTextW(infoPtr->hwndEdit, item->pszText, len+1);
+
+              TRACE("edit control hwndEdit=%p, text len=%d str=%s\n",
+                    infoPtr->hwndEdit, len, debugstr_txt(item->pszText));
+           }
+       }
+    }
+
+
+    /* if the item pointer is not set, then get the data and locate it */
+    if (!item) {
+        item = get_item_data(infoPtr, dis->itemID);
+       if (item == (CBE_ITEMDATA *)CB_ERR) {
+           ERR("invalid item for id %d \n", dis->itemID);
+           return 0;
+       }
+    }
+
+    if (TRACE_ON(comboex)) COMBOEX_DumpItem (item);
+
+    xbase = CBE_STARTOFFSET;
+    if ((item->mask & CBEIF_INDENT) && (dis->itemState & ODS_COMBOEXLBOX)) {
+       INT indent = item->iIndent;
+       if (indent == I_INDENTCALLBACK) {
+           NMCOMBOBOXEXW nmce;
+           ZeroMemory(&nmce, sizeof(nmce));
+           nmce.ceItem.mask = CBEIF_INDENT;
+           nmce.ceItem.lParam = item->lParam;
+           COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);
+           if (nmce.ceItem.mask & CBEIF_DI_SETITEM)
+               item->iIndent = nmce.ceItem.iIndent;
+           indent = nmce.ceItem.iIndent;
+       }
+        xbase += (indent * CBE_INDENT);
+    }
+
+    drawimage = -2;
+    drawstate = ILD_NORMAL;
+    if (item->mask & CBEIF_IMAGE)
+       drawimage = item->iImage;
+    if (dis->itemState & ODS_COMBOEXLBOX) {
+       /* drawing listbox entry */
+       if (dis->itemState & ODS_SELECTED) {
+           if (item->mask & CBEIF_SELECTEDIMAGE)
+               drawimage = item->iSelectedImage;
+           drawstate = ILD_SELECTED;
+       }
+    } else {
+       /* drawing combo/edit entry */
+       if (IsWindowVisible(infoPtr->hwndEdit)) {
+           /* if we have an edit control, the slave the
+             * selection state to the Edit focus state
+            */
+           if (infoPtr->flags & WCBE_EDITFOCUSED) {
+               if (item->mask & CBEIF_SELECTEDIMAGE)
+                   drawimage = item->iSelectedImage;
+               drawstate = ILD_SELECTED;
+           }
+       } else {
+           /* if we don't have an edit control, use
+            * the requested state.
+            */
+           if (dis->itemState & ODS_SELECTED) {
+               if (item->mask & CBEIF_SELECTEDIMAGE)
+                   drawimage = item->iSelectedImage;
+               drawstate = ILD_SELECTED;
+           }
+       }
+    }
+
+    if (infoPtr->himl && !(infoPtr->dwExtStyle & CBES_EX_NOEDITIMAGEINDENT)) {
+       IMAGEINFO iinfo;
+        iinfo.rcImage.left = iinfo.rcImage.right = 0;
+       ImageList_GetImageInfo(infoPtr->himl, 0, &iinfo);
+       xioff = iinfo.rcImage.right - iinfo.rcImage.left + CBE_SEP;
+    }  else xioff = 0;
+
+    /* setup pointer to text to be drawn */
+    str = COMBOEX_GetText(infoPtr, item);
+    if (!str) str = nil;
+
+    len = strlenW (str);
+    GetTextExtentPoint32W (dis->hDC, str, len, &txtsize);
+
+    if (dis->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)) {
+       int overlay = item->iOverlay;
+
+       if (drawimage == I_IMAGECALLBACK) {
+           NMCOMBOBOXEXW nmce;
+           ZeroMemory(&nmce, sizeof(nmce));
+           nmce.ceItem.mask = (drawstate == ILD_NORMAL) ? CBEIF_IMAGE : CBEIF_SELECTEDIMAGE;
+           nmce.ceItem.lParam = item->lParam;
+           COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);
+           if (drawstate == ILD_NORMAL) {
+               if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iImage = nmce.ceItem.iImage;
+               drawimage = nmce.ceItem.iImage;
+           } else if (drawstate == ILD_SELECTED) {
+               if (nmce.ceItem.mask & CBEIF_DI_SETITEM) item->iSelectedImage = nmce.ceItem.iSelectedImage;
+               drawimage =  nmce.ceItem.iSelectedImage;
+           } else ERR("Bad draw state = %d\n", drawstate);
+        }
+
+       if (overlay == I_IMAGECALLBACK) {
+           NMCOMBOBOXEXW nmce;
+           ZeroMemory(&nmce, sizeof(nmce));
+           nmce.ceItem.mask = CBEIF_OVERLAY;
+           nmce.ceItem.lParam = item->lParam;
+           COMBOEX_NotifyItem(infoPtr, CBEN_GETDISPINFOW, &nmce);
+           if (nmce.ceItem.mask & CBEIF_DI_SETITEM)
+               item->iOverlay = nmce.ceItem.iOverlay;
+           overlay = nmce.ceItem.iOverlay;
+       }
+
+       if (drawimage >= 0 &&
+           !(infoPtr->dwExtStyle & (CBES_EX_NOEDITIMAGE | CBES_EX_NOEDITIMAGEINDENT))) {
+           if (overlay > 0) ImageList_SetOverlayImage (infoPtr->himl, overlay, 1);
+           ImageList_Draw (infoPtr->himl, drawimage, dis->hDC, xbase, dis->rcItem.top,
+                           drawstate | (overlay > 0 ? INDEXTOOVERLAYMASK(1) : 0));
+       }
+
+       /* now draw the text */
+       if (!IsWindowVisible (infoPtr->hwndEdit)) {
+           nbkc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
+                               COLOR_HIGHLIGHT : COLOR_WINDOW);
+           bkc = SetBkColor (dis->hDC, nbkc);
+           ntxc = GetSysColor ((dis->itemState & ODS_SELECTED) ?
+                               COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT);
+           txc = SetTextColor (dis->hDC, ntxc);
+           x = xbase + xioff;
+           y = dis->rcItem.top +
+               (dis->rcItem.bottom - dis->rcItem.top - txtsize.cy) / 2;
+           rect.left = x;
+           rect.right = x + txtsize.cx;
+           rect.top = dis->rcItem.top + 1;
+           rect.bottom = dis->rcItem.bottom - 1;
+           TRACE("drawing item %d text, rect=(%ld,%ld)-(%ld,%ld)\n",
+                 dis->itemID, rect.left, rect.top, rect.right, rect.bottom);
+           ExtTextOutW (dis->hDC, x, y, ETO_OPAQUE | ETO_CLIPPED,
+                        &rect, str, len, 0);
+           SetBkColor (dis->hDC, bkc);
+           SetTextColor (dis->hDC, txc);
+       }
+    }
+
+    if (dis->itemAction & ODA_FOCUS) {
+       rect.left = xbase + xioff - 1;
+       rect.right = rect.left + txtsize.cx + 2;
+       rect.top = dis->rcItem.top;
+       rect.bottom = dis->rcItem.bottom;
+       DrawFocusRect(dis->hDC, &rect);
+    }
+
+    return 0;
+}
+
+
+static LRESULT COMBOEX_Destroy (COMBOEX_INFO *infoPtr)
+{
+    if (infoPtr->hwndCombo)
+       DestroyWindow (infoPtr->hwndCombo);
+
+    if (infoPtr->edit) {
+       Free (infoPtr->edit);
+       infoPtr->edit = 0;
+    }
+
+    if (infoPtr->items) {
+        CBE_ITEMDATA *item, *next;
+
+       item = infoPtr->items;
+       while (item) {
+           next = (CBE_ITEMDATA *)item->next;
+           COMBOEX_FreeText (item);
+           Free (item);
+           item = next;
+       }
+       infoPtr->items = 0;
+    }
+
+    if (infoPtr->defaultFont)
+       DeleteObject (infoPtr->defaultFont);
+
+    /* free comboex info data */
+    Free (infoPtr);
+    SetWindowLongW (infoPtr->hwndSelf, 0, 0);
+    return 0;
+}
+
+
+static LRESULT COMBOEX_MeasureItem (COMBOEX_INFO *infoPtr, MEASUREITEMSTRUCT *mis)
+{
+    SIZE mysize;
+    HDC hdc;
+
+    hdc = GetDC (0);
+    GetTextExtentPointA (hdc, "W", 1, &mysize);
+    ReleaseDC (0, hdc);
+    mis->itemHeight = mysize.cy + CBE_EXTRA;
+
+    TRACE("adjusted height hwnd=%p, height=%d\n",
+         infoPtr->hwndSelf, mis->itemHeight);
+
+    return 0;
+}
+
+
+static LRESULT COMBOEX_NCCreate (HWND hwnd)
+{
+    /* WARNING: The COMBOEX_INFO structure is not yet created */
+    DWORD oldstyle, newstyle;
+
+    oldstyle = (DWORD)GetWindowLongW (hwnd, GWL_STYLE);
+    newstyle = oldstyle & ~(WS_VSCROLL | WS_HSCROLL);
+    if (newstyle != oldstyle) {
+       TRACE("req style %08lx, reseting style %08lx\n",
+             oldstyle, newstyle);
+       SetWindowLongW (hwnd, GWL_STYLE, newstyle);
+    }
+    return 1;
+}
+
+
+static LRESULT COMBOEX_NotifyFormat (COMBOEX_INFO *infoPtr, LPARAM lParam)
+{
+    if (lParam == NF_REQUERY) {
+       INT i = SendMessageW(GetParent (infoPtr->hwndSelf),
+                        WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY);
+       infoPtr->NtfUnicode = (i == NFR_UNICODE) ? 1 : 0;
+    }
+    return infoPtr->NtfUnicode ? NFR_UNICODE : NFR_ANSI;
+}
+
+
+static LRESULT COMBOEX_Size (COMBOEX_INFO *infoPtr, INT width, INT height)
+{
+    TRACE("(width=%d, height=%d)\n", width, height);
+
+    MoveWindow (infoPtr->hwndCombo, 0, 0, width, height, TRUE);
+
+    COMBOEX_AdjustEditPos (infoPtr);
+
+    return 0;
+}
+
+
+static LRESULT COMBOEX_WindowPosChanging (COMBOEX_INFO *infoPtr, WINDOWPOS *wp)
+{
+    RECT cbx_wrect, cbx_crect, cb_wrect;
+    UINT width, height;
+
+    GetWindowRect (infoPtr->hwndSelf, &cbx_wrect);
+    GetClientRect (infoPtr->hwndSelf, &cbx_crect);
+    GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
+
+    /* width is winpos value + border width of comboex */
+    width = wp->cx
+           + (cbx_wrect.right-cbx_wrect.left)
+            - (cbx_crect.right-cbx_crect.left);
+
+    TRACE("winpos=(%d,%d %dx%d) flags=0x%08x\n",
+         wp->x, wp->y, wp->cx, wp->cy, wp->flags);
+    TRACE("EX window=(%ld,%ld)-(%ld,%ld), client=(%ld,%ld)-(%ld,%ld)\n",
+         cbx_wrect.left, cbx_wrect.top, cbx_wrect.right, cbx_wrect.bottom,
+         cbx_crect.left, cbx_crect.top, cbx_crect.right, cbx_crect.bottom);
+    TRACE("CB window=(%ld,%ld)-(%ld,%ld), EX setting=(0,0)-(%d,%ld)\n",
+         cb_wrect.left, cb_wrect.top, cb_wrect.right, cb_wrect.bottom,
+         width, cb_wrect.bottom-cb_wrect.top);
+
+    if (width) SetWindowPos (infoPtr->hwndCombo, HWND_TOP, 0, 0,
+                            width,
+                            cb_wrect.bottom-cb_wrect.top,
+                            SWP_NOACTIVATE);
+
+    GetWindowRect (infoPtr->hwndCombo, &cb_wrect);
+
+    /* height is combo window height plus border width of comboex */
+    height =   (cb_wrect.bottom-cb_wrect.top)
+            + (cbx_wrect.bottom-cbx_wrect.top)
+             - (cbx_crect.bottom-cbx_crect.top);
+    if (wp->cy < height) wp->cy = height;
+    if (infoPtr->hwndEdit) {
+       COMBOEX_AdjustEditPos (infoPtr);
+       InvalidateRect (infoPtr->hwndCombo, 0, TRUE);
+    }
+
+    return 0;
+}
+
+static inline int is_delimiter(WCHAR c)
+{
+    switch(c) {
+       case '/':
+       case '\\':
+       case '.':
+           return TRUE;
+    }
+    return FALSE;
+}
+
+static int CALLBACK
+COMBOEX_PathWordBreakProc(LPWSTR lpch, int ichCurrent, int cch, int code)
+{
+    if (code == WB_ISDELIMITER) {
+       return is_delimiter(lpch[ichCurrent]);
+    } else {
+       int dir = (code == WB_LEFT) ? -1 : 1;
+        for(; 0 <= ichCurrent && ichCurrent < cch; ichCurrent += dir)
+           if (is_delimiter(lpch[ichCurrent])) return ichCurrent;
+    }
+    return ichCurrent;
+}
+
+static LRESULT WINAPI
+COMBOEX_EditWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    HWND hwndComboex = (HWND)GetPropA(hwnd, COMBOEX_SUBCLASS_PROP);
+    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwndComboex);
+    NMCBEENDEDITW cbeend;
+    WCHAR edit_text[260];
+    COLORREF obkc;
+    HDC hDC;
+    RECT rect;
+    LRESULT lret;
+
+    TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",
+         hwnd, uMsg, wParam, lParam, infoPtr);
+
+    if (!infoPtr) return 0;
+
+    switch (uMsg)
+    {
+
+       case WM_CHAR:
+           /* handle (ignore) the return character */
+           if (wParam == VK_RETURN) return 0;
+           /* all other characters pass into the real Edit */
+           return CallWindowProcW (infoPtr->prevEditWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+
+       case WM_ERASEBKGND:
+           /*
+            * The following was determined by traces of the native
+            */
+            hDC = (HDC) wParam;
+           obkc = SetBkColor (hDC, GetSysColor (COLOR_WINDOW));
+            GetClientRect (hwnd, &rect);
+           TRACE("erasing (%ld,%ld)-(%ld,%ld)\n",
+                 rect.left, rect.top, rect.right, rect.bottom);
+           ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);
+            SetBkColor (hDC, obkc);
+           return CallWindowProcW (infoPtr->prevEditWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+
+       case WM_KEYDOWN: {
+           INT oldItem, selected, step = 1;
+           CBE_ITEMDATA *item;
+
+           switch ((INT)wParam)
+           {
+           case VK_ESCAPE:
+               /* native version seems to do following for COMBOEX */
+               /*
+                *   GetWindowTextA(Edit,&?, 0x104)             x
+                *   CB_GETCURSEL to Combo rets -1              x
+                *   WM_NOTIFY to COMBOEX parent (rebar)        x
+                *     (CBEN_ENDEDIT{A|W}
+                *      fChanged = FALSE                        x
+                *      inewSelection = -1                      x
+                *      txt="www.hoho"                          x
+                *      iWhy = 3                                x
+                *   CB_GETCURSEL to Combo rets -1              x
+                *   InvalidateRect(Combo, 0)                   x
+                *   WM_SETTEXT to Edit                         x
+                *   EM_SETSEL to Edit (0,0)                    x
+                *   EM_SETSEL to Edit (0,-1)                   x
+                *   RedrawWindow(Combo, 0, 0, 5)               x
+                */
+               TRACE("special code for VK_ESCAPE\n");
+
+               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
+
+               infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
+               cbeend.fChanged = FALSE;
+               cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
+                                                    CB_GETCURSEL, 0, 0);
+               cbeend.iWhy = CBENF_ESCAPE;
+
+               if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) return 0;
+               oldItem = SendMessageW (infoPtr->hwndCombo, CB_GETCURSEL, 0, 0);
+               InvalidateRect (infoPtr->hwndCombo, 0, 0);
+               if (!(item = COMBOEX_FindItem(infoPtr, oldItem))) {
+                   ERR("item %d not found. Problem!\n", oldItem);
+                   break;
+               }
+               infoPtr->selected = oldItem;
+               COMBOEX_SetEditText (infoPtr, item);
+               RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE |
+                             RDW_INVALIDATE);
+               break;
+
+           case VK_RETURN:
+               /* native version seems to do following for COMBOEX */
+               /*
+                *   GetWindowTextA(Edit,&?, 0x104)             x
+                *   CB_GETCURSEL to Combo  rets -1             x
+                *   CB_GETCOUNT to Combo  rets 0
+                *   if >0 loop
+                *       CB_GETITEMDATA to match
+                * *** above 3 lines simulated by FindItem      x
+                *   WM_NOTIFY to COMBOEX parent (rebar)        x
+                *     (CBEN_ENDEDIT{A|W}                       x
+                *        fChanged = TRUE (-1)                  x
+                *        iNewSelection = -1 or selected        x
+                *        txt=                                  x
+                *        iWhy = 2 (CBENF_RETURN)               x
+                *   CB_GETCURSEL to Combo  rets -1             x
+                *   if -1 send CB_SETCURSEL to Combo -1        x
+                *   InvalidateRect(Combo, 0, 0)                x
+                *   SetFocus(Edit)                             x
+                *   CallWindowProc(406615a8, Edit, 0x100, 0xd, 0x1c0001)
+                */
+
+               TRACE("special code for VK_RETURN\n");
+
+               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
+
+               infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
+               selected = SendMessageW (infoPtr->hwndCombo,
+                                        CB_GETCURSEL, 0, 0);
+
+               if (selected != -1) {
+                    cmp_func_t cmptext = get_cmp_func(infoPtr);
+                   item = COMBOEX_FindItem (infoPtr, selected);
+                   TRACE("handling VK_RETURN, selected = %d, selected_text=%s\n",
+                         selected, debugstr_txt(item->pszText));
+                   TRACE("handling VK_RETURN, edittext=%s\n",
+                         debugstr_w(edit_text));
+                   if (cmptext (COMBOEX_GetText(infoPtr, item), edit_text)) {
+                       /* strings not equal -- indicate edit has changed */
+                       selected = -1;
+                   }
+               }
+
+               cbeend.iNewSelection = selected;
+               cbeend.fChanged = TRUE;
+               cbeend.iWhy = CBENF_RETURN;
+               if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) {
+                   /* abort the change, restore previous */
+                   TRACE("Notify requested abort of change\n");
+                   COMBOEX_SetEditText (infoPtr, infoPtr->edit);
+                   RedrawWindow (infoPtr->hwndCombo, 0, 0, RDW_ERASE |
+                                 RDW_INVALIDATE);
+                   return 0;
+               }
+               oldItem = SendMessageW (infoPtr->hwndCombo,CB_GETCURSEL, 0, 0);
+               if (oldItem != -1) {
+                   /* if something is selected, then deselect it */
+                   SendMessageW (infoPtr->hwndCombo, CB_SETCURSEL,
+                                 (WPARAM)-1, 0);
+               }
+               InvalidateRect (infoPtr->hwndCombo, 0, 0);
+               SetFocus(infoPtr->hwndEdit);
+               break;
+
+           case VK_UP:
+               step = -1;
+           case VK_DOWN:
+               /* by default, step is 1 */
+               oldItem = SendMessageW (infoPtr->hwndSelf, CB_GETCURSEL, 0, 0);
+               if (oldItem >= 0 && oldItem + step >= 0)
+                   SendMessageW (infoPtr->hwndSelf, CB_SETCURSEL, oldItem + step, 0);
+               return 0;
+           default:
+               return CallWindowProcW (infoPtr->prevEditWndProc,
+                                      hwnd, uMsg, wParam, lParam);
+           }
+           return 0;
+            }
+
+       case WM_SETFOCUS:
+           /* remember the focus to set state of icon */
+           lret = CallWindowProcW (infoPtr->prevEditWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+           infoPtr->flags |= WCBE_EDITFOCUSED;
+           return lret;
+
+       case WM_KILLFOCUS:
+           /*
+            * do NOTIFY CBEN_ENDEDIT with CBENF_KILLFOCUS
+            */
+           infoPtr->flags &= ~WCBE_EDITFOCUSED;
+           if (infoPtr->flags & WCBE_ACTEDIT) {
+               infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
+
+               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
+               cbeend.fChanged = FALSE;
+               cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
+                                                    CB_GETCURSEL, 0, 0);
+               cbeend.iWhy = CBENF_KILLFOCUS;
+
+               COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text);
+           }
+           /* fall through */
+
+       default:
+           return CallWindowProcW (infoPtr->prevEditWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+    }
+    return 0;
+}
+
+
+static LRESULT WINAPI
+COMBOEX_ComboWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    HWND hwndComboex = (HWND)GetPropA(hwnd, COMBOEX_SUBCLASS_PROP);
+    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwndComboex);
+    NMCBEENDEDITW cbeend;
+    NMMOUSE nmmse;
+    COLORREF obkc;
+    HDC hDC;
+    HWND focusedhwnd;
+    RECT rect;
+    POINT pt;
+    WCHAR edit_text[260];
+
+    TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx, info_ptr=%p\n",
+         hwnd, uMsg, wParam, lParam, infoPtr);
+
+    if (!infoPtr) return 0;
+
+    switch (uMsg)
+    {
+
+    case WM_DRAWITEM:
+           /*
+            * The only way this message should come is from the
+            * child Listbox issuing the message. Flag this so
+            * that ComboEx knows this is listbox.
+            */
+           ((DRAWITEMSTRUCT *)lParam)->itemState |= ODS_COMBOEXLBOX;
+           return CallWindowProcW (infoPtr->prevComboWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+
+    case WM_ERASEBKGND:
+           /*
+            * The following was determined by traces of the native
+            */
+            hDC = (HDC) wParam;
+           obkc = SetBkColor (hDC, GetSysColor (COLOR_WINDOW));
+            GetClientRect (hwnd, &rect);
+           TRACE("erasing (%ld,%ld)-(%ld,%ld)\n",
+                 rect.left, rect.top, rect.right, rect.bottom);
+           ExtTextOutW (hDC, 0, 0, ETO_OPAQUE, &rect, 0, 0, 0);
+            SetBkColor (hDC, obkc);
+           return CallWindowProcW (infoPtr->prevComboWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+
+    case WM_SETCURSOR:
+           /*
+            *  WM_NOTIFY to comboex parent (rebar)
+            *   with NM_SETCURSOR with extra words of 0,0,0,0,0x02010001
+            *  CallWindowProc (previous)
+            */
+           nmmse.dwItemSpec = 0;
+           nmmse.dwItemData = 0;
+           nmmse.pt.x = 0;
+           nmmse.pt.y = 0;
+           nmmse.dwHitInfo = lParam;
+           COMBOEX_Notify (infoPtr, NM_SETCURSOR, (NMHDR *)&nmmse);
+           return CallWindowProcW (infoPtr->prevComboWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+
+    case WM_LBUTTONDOWN:
+           GetClientRect (hwnd, &rect);
+           rect.bottom = rect.top + SendMessageW(infoPtr->hwndSelf,
+                                                 CB_GETITEMHEIGHT, -1, 0);
+           rect.left = rect.right - GetSystemMetrics(SM_CXVSCROLL);
+           POINTSTOPOINT(pt, MAKEPOINTS(lParam));
+           if (PtInRect(&rect, pt))
+               return CallWindowProcW (infoPtr->prevComboWndProc,
+                                       hwnd, uMsg, wParam, lParam);
+           infoPtr->flags |= WCBE_MOUSECAPTURED;
+           SetCapture(hwnd);
+           break;
+
+    case WM_LBUTTONUP:
+           if (!(infoPtr->flags & WCBE_MOUSECAPTURED))
+               return CallWindowProcW (infoPtr->prevComboWndProc,
+                                       hwnd, uMsg, wParam, lParam);
+           ReleaseCapture();
+           infoPtr->flags &= ~WCBE_MOUSECAPTURED;
+           if (infoPtr->flags & WCBE_MOUSEDRAGGED) {
+               infoPtr->flags &= ~WCBE_MOUSEDRAGGED;
+           } else {
+               SendMessageW(hwnd, CB_SHOWDROPDOWN, TRUE, 0);
+           }
+           break;
+
+    case WM_MOUSEMOVE:
+           if ( (infoPtr->flags & WCBE_MOUSECAPTURED) &&
+               !(infoPtr->flags & WCBE_MOUSEDRAGGED)) {
+               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
+               COMBOEX_NotifyDragBegin(infoPtr, edit_text);
+               infoPtr->flags |= WCBE_MOUSEDRAGGED;
+           }
+           return CallWindowProcW (infoPtr->prevComboWndProc,
+                                   hwnd, uMsg, wParam, lParam);
+
+    case WM_COMMAND:
+           switch (HIWORD(wParam)) {
+
+           case EN_UPDATE:
+               /* traces show that COMBOEX does not issue CBN_EDITUPDATE
+                * on the EN_UPDATE
+                */
+               return 0;
+
+           case EN_KILLFOCUS:
+               /*
+                * Native does:
+                *
+                *  GetFocus() retns AA
+                *  GetWindowTextA(Edit)
+                *  CB_GETCURSEL(Combo) (got -1)
+                *  WM_NOTIFY(CBEN_ENDEDITA) with CBENF_KILLFOCUS
+                *  CB_GETCURSEL(Combo) (got -1)
+                *  InvalidateRect(Combo, 0, 0)
+                *  WM_KILLFOCUS(Combo, AA)
+                *  return 0;
+                */
+               focusedhwnd = GetFocus();
+               if (infoPtr->flags & WCBE_ACTEDIT) {
+                   GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
+                   cbeend.fChanged = (infoPtr->flags & WCBE_EDITCHG);
+                   cbeend.iNewSelection = SendMessageW (infoPtr->hwndCombo,
+                                                        CB_GETCURSEL, 0, 0);
+                   cbeend.iWhy = CBENF_KILLFOCUS;
+
+                   infoPtr->flags &= ~(WCBE_ACTEDIT | WCBE_EDITCHG);
+                   if (COMBOEX_NotifyEndEdit (infoPtr, &cbeend, edit_text)) return 0;
+               }
+               /* possible CB_GETCURSEL */
+               InvalidateRect (infoPtr->hwndCombo, 0, 0);
+               if (focusedhwnd)
+                   SendMessageW (infoPtr->hwndCombo, WM_KILLFOCUS,
+                                 (WPARAM)focusedhwnd, 0);
+               return 0;
+
+           case EN_SETFOCUS: {
+               /*
+                * For EN_SETFOCUS this issues the same calls and messages
+                *  as the native seems to do.
+                *
+                * for some cases however native does the following:
+                *   (noticed after SetFocus during LBUTTONDOWN on
+                *    on dropdown arrow)
+                *  WM_GETTEXTLENGTH (Edit);
+                *  WM_GETTEXT (Edit, len+1, str);
+                *  EM_SETSEL (Edit, 0, 0);
+                *  WM_GETTEXTLENGTH (Edit);
+                *  WM_GETTEXT (Edit, len+1, str);
+                *  EM_SETSEL (Edit, 0, len);
+                *  WM_NOTIFY (parent, CBEN_BEGINEDIT)
+                */
+               NMHDR hdr;
+
+               SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, 0);
+               SendMessageW (infoPtr->hwndEdit, EM_SETSEL, 0, -1);
+               COMBOEX_Notify (infoPtr, CBEN_BEGINEDIT, &hdr);
+               infoPtr->flags |= WCBE_ACTEDIT;
+               infoPtr->flags &= ~WCBE_EDITCHG; /* no change yet */
+               return 0;
+               }
+
+           case EN_CHANGE: {
+               /*
+                * For EN_CHANGE this issues the same calls and messages
+                *  as the native seems to do.
+                */
+               WCHAR edit_text[260];
+               LPCWSTR lastwrk;
+                cmp_func_t cmptext = get_cmp_func(infoPtr);
+
+               INT selected = SendMessageW (infoPtr->hwndCombo,
+                                            CB_GETCURSEL, 0, 0);
+
+               /* lstrlenA( lastworkingURL ) */
+
+               GetWindowTextW (infoPtr->hwndEdit, edit_text, 260);
+               if (selected == -1) {
+                   lastwrk = infoPtr->edit->pszText;
+               }
+               else {
+                   CBE_ITEMDATA *item = COMBOEX_FindItem (infoPtr, selected);
+                   lastwrk = COMBOEX_GetText(infoPtr, item);
+               }
+
+               TRACE("handling EN_CHANGE, selected = %d, selected_text=%s\n",
+                     selected, debugstr_w(lastwrk));
+               TRACE("handling EN_CHANGE, edittext=%s\n",
+                     debugstr_w(edit_text));
+
+               /* cmptext is between lastworkingURL and GetWindowText */
+               if (cmptext (lastwrk, edit_text)) {
+                   /* strings not equal -- indicate edit has changed */
+                   infoPtr->flags |= WCBE_EDITCHG;
+               }
+               SendMessageW ( GetParent(infoPtr->hwndSelf), WM_COMMAND,
+                              MAKEWPARAM(GetDlgCtrlID (infoPtr->hwndSelf),
+                                         CBN_EDITCHANGE),
+                              (LPARAM)infoPtr->hwndSelf);
+               return 0;
+               }
+
+           case LBN_SELCHANGE:
+               /*
+                * Therefore from traces there is no additional code here
+                */
+
+               /*
+                * Using native COMCTL32 gets the following:
+                *  1 == SHDOCVW.DLL  issues call/message
+                *  2 == COMCTL32.DLL  issues call/message
+                *  3 == WINE  issues call/message
+                *
+                *
+                * for LBN_SELCHANGE:
+                *    1  CB_GETCURSEL(ComboEx)
+                *    1  CB_GETDROPPEDSTATE(ComboEx)
+                *    1  CallWindowProc( *2* for WM_COMMAND(LBN_SELCHANGE)
+                *    2  CallWindowProc( *3* for WM_COMMAND(LBN_SELCHANGE)
+                **   call CBRollUp( xxx, TRUE for LBN_SELCHANGE, TRUE)
+                *    3  WM_COMMAND(ComboEx, CBN_SELENDOK)
+                *      WM_USER+49(ComboLB, 1,0)  <=============!!!!!!!!!!!
+                *    3  ShowWindow(ComboLB, SW_HIDE)
+                *    3  RedrawWindow(Combo,  RDW_UPDATENOW)
+                *    3  WM_COMMAND(ComboEX, CBN_CLOSEUP)
+                **   end of CBRollUp
+                *    3  WM_COMMAND(ComboEx, CBN_SELCHANGE)  (echo to parent)
+                *    ?  LB_GETCURSEL              <==|
+                *    ?  LB_GETTEXTLEN                |
+                *    ?  LB_GETTEXT                   | Needs to be added to
+                *    ?  WM_CTLCOLOREDIT(ComboEx)     | Combo processing
+                *    ?  LB_GETITEMDATA               |
+                *    ?  WM_DRAWITEM(ComboEx)      <==|
+                */
+           default:
+               break;
+           }/* fall through */
+    default:
+           return CallWindowProcW (infoPtr->prevComboWndProc,
+                                  hwnd, uMsg, wParam, lParam);
+    }
+    return 0;
+}
+
+
+static LRESULT WINAPI
+COMBOEX_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    COMBOEX_INFO *infoPtr = COMBOEX_GetInfoPtr (hwnd);
+
+    TRACE("hwnd=%p msg=%x wparam=%x lParam=%lx\n", hwnd, uMsg, wParam, lParam);
+
+    if (!infoPtr) {
+       if (uMsg == WM_CREATE)
+           return COMBOEX_Create (hwnd, (LPCREATESTRUCTA)lParam);
+       if (uMsg == WM_NCCREATE)
+           COMBOEX_NCCreate (hwnd);
+        return DefWindowProcW (hwnd, uMsg, wParam, lParam);
+    }
+
+    switch (uMsg)
+    {
+        case CBEM_DELETEITEM:
+           return COMBOEX_DeleteItem (infoPtr, wParam);
+
+       case CBEM_GETCOMBOCONTROL:
+           return (LRESULT)infoPtr->hwndCombo;
+
+       case CBEM_GETEDITCONTROL:
+           return (LRESULT)infoPtr->hwndEdit;
+
+       case CBEM_GETEXTENDEDSTYLE:
+           return infoPtr->dwExtStyle;
+
+       case CBEM_GETIMAGELIST:
+           return (LRESULT)infoPtr->himl;
+
+       case CBEM_GETITEMA:
+           return (LRESULT)COMBOEX_GetItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);
+
+       case CBEM_GETITEMW:
+           return (LRESULT)COMBOEX_GetItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);
+
+       case CBEM_GETUNICODEFORMAT:
+           return infoPtr->unicode;
+
+       case CBEM_HASEDITCHANGED:
+           return COMBOEX_HasEditChanged (infoPtr);
+
+       case CBEM_INSERTITEMA:
+           return COMBOEX_InsertItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);
+
+       case CBEM_INSERTITEMW:
+           return COMBOEX_InsertItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);
+
+       case CBEM_SETEXSTYLE:
+       case CBEM_SETEXTENDEDSTYLE:
+           return COMBOEX_SetExtendedStyle (infoPtr, (DWORD)wParam, (DWORD)lParam);
+
+       case CBEM_SETIMAGELIST:
+           return (LRESULT)COMBOEX_SetImageList (infoPtr, (HIMAGELIST)lParam);
+
+       case CBEM_SETITEMA:
+           return COMBOEX_SetItemA (infoPtr, (COMBOBOXEXITEMA *)lParam);
+
+       case CBEM_SETITEMW:
+           return COMBOEX_SetItemW (infoPtr, (COMBOBOXEXITEMW *)lParam);
+
+       case CBEM_SETUNICODEFORMAT:
+           return COMBOEX_SetUnicodeFormat (infoPtr, wParam);
+
+       /*case CBEM_SETWINDOWTHEME:
+           FIXME("CBEM_SETWINDOWTHEME: stub\n");*/
+
+       case WM_SETTEXT:
+       case WM_GETTEXT:
+            return SendMessageW(infoPtr->hwndEdit, uMsg, wParam, lParam);
+
+/*   Combo messages we are not sure if we need to process or just forward */
+       case CB_GETDROPPEDCONTROLRECT:
+       case CB_GETITEMHEIGHT:
+       case CB_GETLBTEXT:
+       case CB_GETLBTEXTLEN:
+       case CB_GETEXTENDEDUI:
+       case CB_LIMITTEXT:
+       case CB_RESETCONTENT:
+       case CB_SELECTSTRING:
+
+/*   Combo messages OK to just forward to the regular COMBO */
+       case CB_GETCOUNT:
+       case CB_GETCURSEL:
+       case CB_GETDROPPEDSTATE:
+        case CB_SETDROPPEDWIDTH:
+        case CB_SETEXTENDEDUI:
+        case CB_SHOWDROPDOWN:
+           return SendMessageW (infoPtr->hwndCombo, uMsg, wParam, lParam);
+
+/*   Combo messages we need to process specially */
+        case CB_FINDSTRINGEXACT:
+           return COMBOEX_FindStringExact (infoPtr, (INT)wParam, (LPCWSTR)lParam);
+
+       case CB_GETITEMDATA:
+           return COMBOEX_GetItemData (infoPtr, (INT)wParam);
+
+       case CB_SETCURSEL:
+           return COMBOEX_SetCursel (infoPtr, (INT)wParam);
+
+       case CB_SETITEMDATA:
+           return COMBOEX_SetItemData (infoPtr, (INT)wParam, (DWORD)lParam);
+
+       case CB_SETITEMHEIGHT:
+           return COMBOEX_SetItemHeight (infoPtr, (INT)wParam, (UINT)lParam);
+
+
+
+/*   Window messages passed to parent */
+       case WM_COMMAND:
+           return COMBOEX_Command (infoPtr, wParam, lParam);
+
+       case WM_NOTIFY:
+           if (infoPtr->NtfUnicode)
+               return SendMessageW (GetParent (hwnd), uMsg, wParam, lParam);
+           else
+               return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
+
+
+/*   Window messages we need to process */
+        case WM_DELETEITEM:
+           return COMBOEX_WM_DeleteItem (infoPtr, (DELETEITEMSTRUCT *)lParam);
+
+        case WM_DRAWITEM:
+            return COMBOEX_DrawItem (infoPtr, (DRAWITEMSTRUCT *)lParam);
+
+       case WM_DESTROY:
+           return COMBOEX_Destroy (infoPtr);
+
+        case WM_MEASUREITEM:
+            return COMBOEX_MeasureItem (infoPtr, (MEASUREITEMSTRUCT *)lParam);
+
+        case WM_NOTIFYFORMAT:
+           return COMBOEX_NotifyFormat (infoPtr, lParam);
+
+       case WM_SIZE:
+           return COMBOEX_Size (infoPtr, LOWORD(lParam), HIWORD(lParam));
+
+        case WM_WINDOWPOSCHANGING:
+           return COMBOEX_WindowPosChanging (infoPtr, (WINDOWPOS *)lParam);
+
+       default:
+           if ((uMsg >= WM_USER) && (uMsg < WM_APP))
+               ERR("unknown msg %04x wp=%08x lp=%08lx\n",uMsg,wParam,lParam);
+           return DefWindowProcW (hwnd, uMsg, wParam, lParam);
+    }
+    return 0;
+}
+
+
+void COMBOEX_Register (void)
+{
+    WNDCLASSW wndClass;
+
+    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
+    wndClass.style         = CS_GLOBALCLASS;
+    wndClass.lpfnWndProc   = (WNDPROC)COMBOEX_WindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(COMBOEX_INFO *);
+    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
+    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    wndClass.lpszClassName = WC_COMBOBOXEXW;
+
+    RegisterClassW (&wndClass);
+}
+
+
+void COMBOEX_Unregister (void)
+{
+    UnregisterClassW (WC_COMBOBOXEXW, NULL);
+}
index aa3e997..c30d223 100644 (file)
-LIBRARY comctl32.dll\r
-EXPORTS\r
-MenuHelp@28 @2\r
-ShowHideMenuCtl@12 @3\r
-GetEffectiveClientRect@12 @4\r
-DrawStatusTextA@16 @5\r
-CreateStatusWindowA@16 @6\r
-CreateToolbar@32 @7\r
-CreateMappedBitmap@20 @8\r
-DPA_LoadStream@16 @9 NONAME\r
-DPA_SaveStream@16 @10 NONAME\r
-DPA_Merge@24 @11 NONAME\r
-MakeDragList@4 @13\r
-LBItemFromPt@16 @14\r
-DrawInsert@12 @15\r
-CreateUpDownControl@48 @16\r
-InitCommonControls@0 @17\r
-Alloc@4 @71 NONAME\r
-ReAlloc@8 @72 NONAME\r
-Free@4 @73 NONAME\r
-GetSize@4 @74 NONAME\r
-CreateMRUListA@4 @151 NONAME\r
-FreeMRUList@4 @152 NONAME\r
-AddMRUStringA@8 @153 NONAME\r
-EnumMRUListA@16 @154 NONAME\r
-FindMRUStringA@12 @155 NONAME\r
-DelMRUString@8 @156 NONAME\r
-CreateMRUListLazyA@16 @157 NONAME\r
-AddMRUData@12 @167 NONAME\r
-FindMRUData@16 @169 NONAME\r
-Str_GetPtrA@12 @233 NONAME\r
-Str_SetPtrA@8 @234 NONAME\r
-Str_GetPtrW@12 @235 NONAME\r
-Str_SetPtrW@8 @236 NONAME\r
-DSA_Create@8 @320 NONAME\r
-DSA_Destroy@4 @321 NONAME\r
-DSA_GetItem@12 @322 NONAME\r
-DSA_GetItemPtr@8 @323 NONAME\r
-DSA_InsertItem@12 @324 NONAME\r
-DSA_SetItem@12 @325 NONAME\r
-DSA_DeleteItem@8 @326 NONAME\r
-DSA_DeleteAllItems@4 @327 NONAME\r
-DPA_Create@4 @328 NONAME\r
-DPA_Destroy@4 @329 NONAME\r
-DPA_Grow@8 @330 NONAME\r
-DPA_Clone@8 @331 NONAME\r
-DPA_GetPtr@8 @332 NONAME\r
-DPA_GetPtrIndex@8 @333 NONAME\r
-DPA_InsertPtr@12 @334 NONAME\r
-DPA_SetPtr@12 @335 NONAME\r
-DPA_DeletePtr@8 @336 NONAME\r
-DPA_DeleteAllPtrs@4 @337 NONAME\r
-DPA_Sort@12 @338 NONAME\r
-DPA_Search@24 @339 NONAME\r
-DPA_CreateEx@8 @340 NONAME\r
-SendNotify@16 @341 NONAME\r
-SendNotifyEx@20 @342 NONAME\r
-StrChrA@8 @350 NONAME\r
-StrRChrA@12 @351 NONAME\r
-StrCmpNA@12 @352 NONAME\r
-StrCmpNIA@12 @353 NONAME\r
-StrStrA@8 @354 NONAME\r
-StrStrIA@8 @355 NONAME\r
-StrCSpnA@8 @356 NONAME\r
-StrToIntA@4 @357 NONAME\r
-StrChrW@8 @358 NONAME\r
-StrRChrW@12 @359 NONAME\r
-StrCmpNW@12 @360 NONAME\r
-StrCmpNIW@12 @361 NONAME\r
-StrStrW@8 @362 NONAME\r
-StrStrIW@8 @363 NONAME\r
-StrSpnW@8 @364 NONAME\r
-StrToIntW@4 @365 NONAME\r
-SmoothScrollWindow@4 @382 NONAME\r
-DPA_EnumCallback@12 @385 NONAME\r
-DPA_DestroyCallback@12 @386 NONAME\r
-DSA_EnumCallback@12 @387 NONAME\r
-DSA_DestroyCallback@12 @388 NONAME\r
-CreateMRUListW@4 @400 NONAME\r
-AddMRUStringW@8 @401 NONAME\r
-FindMRUStringW@12 @402 NONAME\r
-EnumMRUListW@16 @403 NONAME\r
-CreateMRUListLazyW@16 @404 NONAME\r
-SetWindowSubclass@16 @410\r
-GetWindowSubclass@16 @411\r
-RemoveWindowSubclass@12 @412\r
-DefSubclassProc@16 @413\r
-DrawTextWrap@20 @415 NONAME\r
-ExtTextOutWrap@32 @417 NONAME\r
-GetTextExtentPointWrap@16 @419 NONAME\r
-CreatePropertySheetPage@4=CreatePropertySheetPageA@4 @12\r
-CreatePropertySheetPageA@4 @18\r
-CreatePropertySheetPageW@4 @19\r
-CreateStatusWindow@16=CreateStatusWindowA@16 @20\r
-CreateStatusWindowW@16 @21\r
-CreateToolbarEx@52 @22\r
-DestroyPropertySheetPage@4 @23\r
-DllGetVersion@4=COMCTL32_DllGetVersion@4 @24\r
-DllInstall@8=COMCTL32_DllInstall@8 @25\r
-DrawStatusText@16=DrawStatusTextA@16 @26\r
-DrawStatusTextW@16 @27\r
-FlatSB_EnableScrollBar@12 @28\r
-FlatSB_GetScrollInfo@12 @29\r
-FlatSB_GetScrollPos@8 @30\r
-FlatSB_GetScrollProp@12 @31\r
-FlatSB_GetScrollRange@16 @32\r
-FlatSB_SetScrollInfo@16 @33\r
-FlatSB_SetScrollPos@16 @34\r
-FlatSB_SetScrollProp@16 @35\r
-FlatSB_SetScrollRange@20 @36\r
-FlatSB_ShowScrollBar@12 @37\r
-GetMUILanguage@0 @38\r
-ImageList_Add@12 @39\r
-ImageList_AddIcon@8 @40\r
-ImageList_AddMasked@12 @41\r
-ImageList_BeginDrag@16 @42\r
-ImageList_Copy@20 @43\r
-ImageList_Create@20 @44\r
-ImageList_Destroy@4 @45\r
-ImageList_DragEnter@12 @46\r
-ImageList_DragLeave@4 @47\r
-ImageList_DragMove@8 @48\r
-ImageList_DragShowNolock@4 @49\r
-ImageList_Draw@24 @50\r
-ImageList_DrawEx@40 @51\r
-ImageList_DrawIndirect@4 @52\r
-ImageList_Duplicate@4 @53\r
-ImageList_EndDrag@0 @54\r
-ImageList_GetBkColor@4 @55\r
-ImageList_GetDragImage@8 @56\r
-ImageList_GetFlags@4 @57\r
-ImageList_GetIcon@12 @58\r
-ImageList_GetIconSize@12 @59\r
-ImageList_GetImageCount@4 @60\r
-ImageList_GetImageInfo@12 @61\r
-ImageList_GetImageRect@12 @62\r
-ImageList_LoadImage@28=ImageList_LoadImageA@28 @63\r
-ImageList_LoadImageA@28 @64\r
-ImageList_LoadImageW@28 @65\r
-ImageList_Merge@24 @66\r
-ImageList_Read@4 @67\r
-ImageList_Remove@8 @68\r
-ImageList_Replace@16 @69\r
-ImageList_ReplaceIcon@12 @70\r
-ImageList_SetBkColor@8 @75\r
-ImageList_SetDragCursorImage@16 @76\r
-ImageList_SetFilter@12 @77\r
-ImageList_SetFlags@8 @78\r
-ImageList_SetIconSize@12 @79\r
-ImageList_SetImageCount@8 @80\r
-ImageList_SetOverlayImage@12 @81\r
-ImageList_Write@8 @82\r
-InitCommonControlsEx@4 @83\r
-InitMUILanguage@4 @84\r
-InitializeFlatSB@4 @85\r
-PropertySheet@4=PropertySheetA@4 @86\r
-PropertySheetA@4 @87\r
-PropertySheetW@4 @88\r
-UninitializeFlatSB@4 @89\r
-_TrackMouseEvent@4 @90\r
+LIBRARY comctl32.dll
+EXPORTS
+MenuHelp@28 @2
+ShowHideMenuCtl@12 @3
+GetEffectiveClientRect@12 @4
+DrawStatusTextA@16 @5
+CreateStatusWindowA@16 @6
+CreateToolbar@32 @7
+CreateMappedBitmap@20 @8
+DPA_LoadStream@16 @9 NONAME
+DPA_SaveStream@16 @10 NONAME
+DPA_Merge@24 @11 NONAME
+MakeDragList@4 @13
+LBItemFromPt@16 @14
+DrawInsert@12 @15
+CreateUpDownControl@48 @16
+InitCommonControls@0 @17
+Alloc@4 @71 NONAME
+ReAlloc@8 @72 NONAME
+Free@4 @73 NONAME
+GetSize@4 @74 NONAME
+CreateMRUListA@4 @151 NONAME
+FreeMRUList@4 @152 NONAME
+AddMRUStringA@8 @153 NONAME
+EnumMRUListA@16 @154 NONAME
+FindMRUStringA@12 @155 NONAME
+DelMRUString@8 @156 NONAME
+CreateMRUListLazyA@16 @157 NONAME
+AddMRUData@12 @167 NONAME
+FindMRUData@16 @169 NONAME
+Str_GetPtrA@12 @233 NONAME
+Str_SetPtrA@8 @234 NONAME
+Str_GetPtrW@12 @235 NONAME
+Str_SetPtrW@8 @236 NONAME
+DSA_Create@8 @320 NONAME
+DSA_Destroy@4 @321 NONAME
+DSA_GetItem@12 @322 NONAME
+DSA_GetItemPtr@8 @323 NONAME
+DSA_InsertItem@12 @324 NONAME
+DSA_SetItem@12 @325 NONAME
+DSA_DeleteItem@8 @326 NONAME
+DSA_DeleteAllItems@4 @327 NONAME
+DPA_Create@4 @328 NONAME
+DPA_Destroy@4 @329 NONAME
+DPA_Grow@8 @330 NONAME
+DPA_Clone@8 @331 NONAME
+DPA_GetPtr@8 @332 NONAME
+DPA_GetPtrIndex@8 @333 NONAME
+DPA_InsertPtr@12 @334 NONAME
+DPA_SetPtr@12 @335 NONAME
+DPA_DeletePtr@8 @336 NONAME
+DPA_DeleteAllPtrs@4 @337 NONAME
+DPA_Sort@12 @338 NONAME
+DPA_Search@24 @339 NONAME
+DPA_CreateEx@8 @340 NONAME
+SendNotify@16 @341 NONAME
+SendNotifyEx@20 @342 NONAME
+StrChrA@8 @350 NONAME
+StrRChrA@12 @351 NONAME
+StrCmpNA@12 @352 NONAME
+StrCmpNIA@12 @353 NONAME
+StrStrA@8 @354 NONAME
+StrStrIA@8 @355 NONAME
+StrCSpnA@8 @356 NONAME
+StrToIntA@4 @357 NONAME
+StrChrW@8 @358 NONAME
+StrRChrW@12 @359 NONAME
+StrCmpNW@12 @360 NONAME
+StrCmpNIW@12 @361 NONAME
+StrStrW@8 @362 NONAME
+StrStrIW@8 @363 NONAME
+StrSpnW@8 @364 NONAME
+StrToIntW@4 @365 NONAME
+SmoothScrollWindow@4 @382 NONAME
+DPA_EnumCallback@12 @385 NONAME
+DPA_DestroyCallback@12 @386 NONAME
+DSA_EnumCallback@12 @387 NONAME
+DSA_DestroyCallback@12 @388 NONAME
+CreateMRUListW@4 @400 NONAME
+AddMRUStringW@8 @401 NONAME
+FindMRUStringW@12 @402 NONAME
+EnumMRUListW@16 @403 NONAME
+CreateMRUListLazyW@16 @404 NONAME
+SetWindowSubclass@16 @410
+GetWindowSubclass@16 @411
+RemoveWindowSubclass@12 @412
+DefSubclassProc@16 @413
+DrawTextWrap@20 @415 NONAME
+ExtTextOutWrap@32 @417 NONAME
+GetTextExtentPointWrap@16 @419 NONAME
+CreatePropertySheetPage@4=CreatePropertySheetPageA@4 @12
+CreatePropertySheetPageA@4 @18
+CreatePropertySheetPageW@4 @19
+CreateStatusWindow@16=CreateStatusWindowA@16 @20
+CreateStatusWindowW@16 @21
+CreateToolbarEx@52 @22
+DestroyPropertySheetPage@4 @23
+DllGetVersion@4=COMCTL32_DllGetVersion@4 @24
+DllInstall@8=COMCTL32_DllInstall@8 @25
+DrawStatusText@16=DrawStatusTextA@16 @26
+DrawStatusTextW@16 @27
+FlatSB_EnableScrollBar@12 @28
+FlatSB_GetScrollInfo@12 @29
+FlatSB_GetScrollPos@8 @30
+FlatSB_GetScrollProp@12 @31
+FlatSB_GetScrollRange@16 @32
+FlatSB_SetScrollInfo@16 @33
+FlatSB_SetScrollPos@16 @34
+FlatSB_SetScrollProp@16 @35
+FlatSB_SetScrollRange@20 @36
+FlatSB_ShowScrollBar@12 @37
+GetMUILanguage@0 @38
+ImageList_Add@12 @39
+ImageList_AddIcon@8 @40
+ImageList_AddMasked@12 @41
+ImageList_BeginDrag@16 @42
+ImageList_Copy@20 @43
+ImageList_Create@20 @44
+ImageList_Destroy@4 @45
+ImageList_DragEnter@12 @46
+ImageList_DragLeave@4 @47
+ImageList_DragMove@8 @48
+ImageList_DragShowNolock@4 @49
+ImageList_Draw@24 @50
+ImageList_DrawEx@40 @51
+ImageList_DrawIndirect@4 @52
+ImageList_Duplicate@4 @53
+ImageList_EndDrag@0 @54
+ImageList_GetBkColor@4 @55
+ImageList_GetDragImage@8 @56
+ImageList_GetFlags@4 @57
+ImageList_GetIcon@12 @58
+ImageList_GetIconSize@12 @59
+ImageList_GetImageCount@4 @60
+ImageList_GetImageInfo@12 @61
+ImageList_GetImageRect@12 @62
+ImageList_LoadImage@28=ImageList_LoadImageA@28 @63
+ImageList_LoadImageA@28 @64
+ImageList_LoadImageW@28 @65
+ImageList_Merge@24 @66
+ImageList_Read@4 @67
+ImageList_Remove@8 @68
+ImageList_Replace@16 @69
+ImageList_ReplaceIcon@12 @70
+ImageList_SetBkColor@8 @75
+ImageList_SetDragCursorImage@16 @76
+ImageList_SetFilter@12 @77
+ImageList_SetFlags@8 @78
+ImageList_SetIconSize@12 @79
+ImageList_SetImageCount@8 @80
+ImageList_SetOverlayImage@12 @81
+ImageList_Write@8 @82
+InitCommonControlsEx@4 @83
+InitMUILanguage@4 @84
+InitializeFlatSB@4 @85
+PropertySheet@4=PropertySheetA@4 @86
+PropertySheetA@4 @87
+PropertySheetW@4 @88
+UninitializeFlatSB@4 @89
+_TrackMouseEvent@4 @90
index 18a180b..f779211 100644 (file)
-LIBRARY comctl32.dll\r
-EXPORTS\r
-MenuHelp=MenuHelp@28 @2\r
-ShowHideMenuCtl=ShowHideMenuCtl@12 @3\r
-GetEffectiveClientRect=GetEffectiveClientRect@12 @4\r
-DrawStatusTextA=DrawStatusTextA@16 @5\r
-CreateStatusWindowA=CreateStatusWindowA@16 @6\r
-CreateToolbar=CreateToolbar@32 @7\r
-CreateMappedBitmap=CreateMappedBitmap@20 @8\r
-DPA_LoadStream=DPA_LoadStream@16 @9 NONAME\r
-DPA_SaveStream=DPA_SaveStream@16 @10 NONAME\r
-DPA_Merge=DPA_Merge@24 @11 NONAME\r
-MakeDragList=MakeDragList@4 @13\r
-LBItemFromPt=LBItemFromPt@16 @14\r
-DrawInsert=DrawInsert@12 @15\r
-CreateUpDownControl=CreateUpDownControl@48 @16\r
-InitCommonControls=InitCommonControls@0 @17\r
-Alloc=Alloc@4 @71 NONAME\r
-ReAlloc=ReAlloc@8 @72 NONAME\r
-Free=Free@4 @73 NONAME\r
-GetSize=GetSize@4 @74 NONAME\r
-CreateMRUListA=CreateMRUListA@4 @151 NONAME\r
-FreeMRUList=FreeMRUList@4 @152 NONAME\r
-AddMRUStringA=AddMRUStringA@8 @153 NONAME\r
-EnumMRUListA=EnumMRUListA@16 @154 NONAME\r
-FindMRUStringA=FindMRUStringA@12 @155 NONAME\r
-DelMRUString=DelMRUString@8 @156 NONAME\r
-CreateMRUListLazyA=CreateMRUListLazyA@16 @157 NONAME\r
-AddMRUData=AddMRUData@12 @167 NONAME\r
-FindMRUData=FindMRUData@16 @169 NONAME\r
-Str_GetPtrA=Str_GetPtrA@12 @233 NONAME\r
-Str_SetPtrA=Str_SetPtrA@8 @234 NONAME\r
-Str_GetPtrW=Str_GetPtrW@12 @235 NONAME\r
-Str_SetPtrW=Str_SetPtrW@8 @236 NONAME\r
-DSA_Create=DSA_Create@8 @320 NONAME\r
-DSA_Destroy=DSA_Destroy@4 @321 NONAME\r
-DSA_GetItem=DSA_GetItem@12 @322 NONAME\r
-DSA_GetItemPtr=DSA_GetItemPtr@8 @323 NONAME\r
-DSA_InsertItem=DSA_InsertItem@12 @324 NONAME\r
-DSA_SetItem=DSA_SetItem@12 @325 NONAME\r
-DSA_DeleteItem=DSA_DeleteItem@8 @326 NONAME\r
-DSA_DeleteAllItems=DSA_DeleteAllItems@4 @327 NONAME\r
-DPA_Create=DPA_Create@4 @328 NONAME\r
-DPA_Destroy=DPA_Destroy@4 @329 NONAME\r
-DPA_Grow=DPA_Grow@8 @330 NONAME\r
-DPA_Clone=DPA_Clone@8 @331 NONAME\r
-DPA_GetPtr=DPA_GetPtr@8 @332 NONAME\r
-DPA_GetPtrIndex=DPA_GetPtrIndex@8 @333 NONAME\r
-DPA_InsertPtr=DPA_InsertPtr@12 @334 NONAME\r
-DPA_SetPtr=DPA_SetPtr@12 @335 NONAME\r
-DPA_DeletePtr=DPA_DeletePtr@8 @336 NONAME\r
-DPA_DeleteAllPtrs=DPA_DeleteAllPtrs@4 @337 NONAME\r
-DPA_Sort=DPA_Sort@12 @338 NONAME\r
-DPA_Search=DPA_Search@24 @339 NONAME\r
-DPA_CreateEx=DPA_CreateEx@8 @340 NONAME\r
-SendNotify=SendNotify@16 @341 NONAME\r
-SendNotifyEx=SendNotifyEx@20 @342 NONAME\r
-StrChrA=StrChrA@8 @350 NONAME\r
-StrRChrA=StrRChrA@12 @351 NONAME\r
-StrCmpNA=StrCmpNA@12 @352 NONAME\r
-StrCmpNIA=StrCmpNIA@12 @353 NONAME\r
-StrStrA=StrStrA@8 @354 NONAME\r
-StrStrIA=StrStrIA@8 @355 NONAME\r
-StrCSpnA=StrCSpnA@8 @356 NONAME\r
-StrToIntA=StrToIntA@4 @357 NONAME\r
-StrChrW=StrChrW@8 @358 NONAME\r
-StrRChrW=StrRChrW@12 @359 NONAME\r
-StrCmpNW=StrCmpNW@12 @360 NONAME\r
-StrCmpNIW=StrCmpNIW@12 @361 NONAME\r
-StrStrW=StrStrW@8 @362 NONAME\r
-StrStrIW=StrStrIW@8 @363 NONAME\r
-StrSpnW=StrSpnW@8 @364 NONAME\r
-StrToIntW=StrToIntW@4 @365 NONAME\r
-SmoothScrollWindow=SmoothScrollWindow@4 @382 NONAME\r
-DPA_EnumCallback=DPA_EnumCallback@12 @385 NONAME\r
-DPA_DestroyCallback=DPA_DestroyCallback@12 @386 NONAME\r
-DSA_EnumCallback=DSA_EnumCallback@12 @387 NONAME\r
-DSA_DestroyCallback=DSA_DestroyCallback@12 @388 NONAME\r
-CreateMRUListW=CreateMRUListW@4 @400 NONAME\r
-AddMRUStringW=AddMRUStringW@8 @401 NONAME\r
-FindMRUStringW=FindMRUStringW@12 @402 NONAME\r
-EnumMRUListW=EnumMRUListW@16 @403 NONAME\r
-CreateMRUListLazyW=CreateMRUListLazyW@16 @404 NONAME\r
-SetWindowSubclass=SetWindowSubclass@16 @410\r
-GetWindowSubclass=GetWindowSubclass@16 @411\r
-RemoveWindowSubclass=RemoveWindowSubclass@12 @412\r
-DefSubclassProc=DefSubclassProc@16 @413\r
-DrawTextWrap=DrawTextWrap@20 @415 NONAME\r
-ExtTextOutWrap=ExtTextOutWrap@32 @417 NONAME\r
-GetTextExtentPointWrap=GetTextExtentPointWrap@16 @419 NONAME\r
-CreatePropertySheetPage=CreatePropertySheetPageA@4 @12\r
-CreatePropertySheetPageA=CreatePropertySheetPageA@4 @18\r
-CreatePropertySheetPageW=CreatePropertySheetPageW@4 @19\r
-CreateStatusWindow=CreateStatusWindowA@16 @20\r
-CreateStatusWindowW=CreateStatusWindowW@16 @21\r
-CreateToolbarEx=CreateToolbarEx@52 @22\r
-DestroyPropertySheetPage=DestroyPropertySheetPage@4 @23\r
-DllGetVersion=COMCTL32_DllGetVersion@4 @24\r
-DllInstall=COMCTL32_DllInstall@8 @25\r
-DrawStatusText=DrawStatusTextA@16 @26\r
-DrawStatusTextW=DrawStatusTextW@16 @27\r
-FlatSB_EnableScrollBar=FlatSB_EnableScrollBar@12 @28\r
-FlatSB_GetScrollInfo=FlatSB_GetScrollInfo@12 @29\r
-FlatSB_GetScrollPos=FlatSB_GetScrollPos@8 @30\r
-FlatSB_GetScrollProp=FlatSB_GetScrollProp@12 @31\r
-FlatSB_GetScrollRange=FlatSB_GetScrollRange@16 @32\r
-FlatSB_SetScrollInfo=FlatSB_SetScrollInfo@16 @33\r
-FlatSB_SetScrollPos=FlatSB_SetScrollPos@16 @34\r
-FlatSB_SetScrollProp=FlatSB_SetScrollProp@16 @35\r
-FlatSB_SetScrollRange=FlatSB_SetScrollRange@20 @36\r
-FlatSB_ShowScrollBar=FlatSB_ShowScrollBar@12 @37\r
-GetMUILanguage=GetMUILanguage@0 @38\r
-ImageList_Add=ImageList_Add@12 @39\r
-ImageList_AddIcon=ImageList_AddIcon@8 @40\r
-ImageList_AddMasked=ImageList_AddMasked@12 @41\r
-ImageList_BeginDrag=ImageList_BeginDrag@16 @42\r
-ImageList_Copy=ImageList_Copy@20 @43\r
-ImageList_Create=ImageList_Create@20 @44\r
-ImageList_Destroy=ImageList_Destroy@4 @45\r
-ImageList_DragEnter=ImageList_DragEnter@12 @46\r
-ImageList_DragLeave=ImageList_DragLeave@4 @47\r
-ImageList_DragMove=ImageList_DragMove@8 @48\r
-ImageList_DragShowNolock=ImageList_DragShowNolock@4 @49\r
-ImageList_Draw=ImageList_Draw@24 @50\r
-ImageList_DrawEx=ImageList_DrawEx@40 @51\r
-ImageList_DrawIndirect=ImageList_DrawIndirect@4 @52\r
-ImageList_Duplicate=ImageList_Duplicate@4 @53\r
-ImageList_EndDrag=ImageList_EndDrag@0 @54\r
-ImageList_GetBkColor=ImageList_GetBkColor@4 @55\r
-ImageList_GetDragImage=ImageList_GetDragImage@8 @56\r
-ImageList_GetFlags=ImageList_GetFlags@4 @57\r
-ImageList_GetIcon=ImageList_GetIcon@12 @58\r
-ImageList_GetIconSize=ImageList_GetIconSize@12 @59\r
-ImageList_GetImageCount=ImageList_GetImageCount@4 @60\r
-ImageList_GetImageInfo=ImageList_GetImageInfo@12 @61\r
-ImageList_GetImageRect=ImageList_GetImageRect@12 @62\r
-ImageList_LoadImage=ImageList_LoadImageA@28 @63\r
-ImageList_LoadImageA=ImageList_LoadImageA@28 @64\r
-ImageList_LoadImageW=ImageList_LoadImageW@28 @65\r
-ImageList_Merge=ImageList_Merge@24 @66\r
-ImageList_Read=ImageList_Read@4 @67\r
-ImageList_Remove=ImageList_Remove@8 @68\r
-ImageList_Replace=ImageList_Replace@16 @69\r
-ImageList_ReplaceIcon=ImageList_ReplaceIcon@12 @70\r
-ImageList_SetBkColor=ImageList_SetBkColor@8 @75\r
-ImageList_SetDragCursorImage=ImageList_SetDragCursorImage@16 @76\r
-ImageList_SetFilter=ImageList_SetFilter@12 @77\r
-ImageList_SetFlags=ImageList_SetFlags@8 @78\r
-ImageList_SetIconSize=ImageList_SetIconSize@12 @79\r
-ImageList_SetImageCount=ImageList_SetImageCount@8 @80\r
-ImageList_SetOverlayImage=ImageList_SetOverlayImage@12 @81\r
-ImageList_Write=ImageList_Write@8 @82\r
-InitCommonControlsEx=InitCommonControlsEx@4 @83\r
-InitMUILanguage=InitMUILanguage@4 @84\r
-InitializeFlatSB=InitializeFlatSB@4 @85\r
-PropertySheet=PropertySheetA@4 @86\r
-PropertySheetA=PropertySheetA@4 @87\r
-PropertySheetW=PropertySheetW@4 @88\r
-UninitializeFlatSB=UninitializeFlatSB@4 @89\r
-_TrackMouseEvent=_TrackMouseEvent@4 @90\r
+LIBRARY comctl32.dll
+EXPORTS
+MenuHelp=MenuHelp@28 @2
+ShowHideMenuCtl=ShowHideMenuCtl@12 @3
+GetEffectiveClientRect=GetEffectiveClientRect@12 @4
+DrawStatusTextA=DrawStatusTextA@16 @5
+CreateStatusWindowA=CreateStatusWindowA@16 @6
+CreateToolbar=CreateToolbar@32 @7
+CreateMappedBitmap=CreateMappedBitmap@20 @8
+DPA_LoadStream=DPA_LoadStream@16 @9 NONAME
+DPA_SaveStream=DPA_SaveStream@16 @10 NONAME
+DPA_Merge=DPA_Merge@24 @11 NONAME
+MakeDragList=MakeDragList@4 @13
+LBItemFromPt=LBItemFromPt@16 @14
+DrawInsert=DrawInsert@12 @15
+CreateUpDownControl=CreateUpDownControl@48 @16
+InitCommonControls=InitCommonControls@0 @17
+Alloc=Alloc@4 @71 NONAME
+ReAlloc=ReAlloc@8 @72 NONAME
+Free=Free@4 @73 NONAME
+GetSize=GetSize@4 @74 NONAME
+CreateMRUListA=CreateMRUListA@4 @151 NONAME
+FreeMRUList=FreeMRUList@4 @152 NONAME
+AddMRUStringA=AddMRUStringA@8 @153 NONAME
+EnumMRUListA=EnumMRUListA@16 @154 NONAME
+FindMRUStringA=FindMRUStringA@12 @155 NONAME
+DelMRUString=DelMRUString@8 @156 NONAME
+CreateMRUListLazyA=CreateMRUListLazyA@16 @157 NONAME
+AddMRUData=AddMRUData@12 @167 NONAME
+FindMRUData=FindMRUData@16 @169 NONAME
+Str_GetPtrA=Str_GetPtrA@12 @233 NONAME
+Str_SetPtrA=Str_SetPtrA@8 @234 NONAME
+Str_GetPtrW=Str_GetPtrW@12 @235 NONAME
+Str_SetPtrW=Str_SetPtrW@8 @236 NONAME
+DSA_Create=DSA_Create@8 @320 NONAME
+DSA_Destroy=DSA_Destroy@4 @321 NONAME
+DSA_GetItem=DSA_GetItem@12 @322 NONAME
+DSA_GetItemPtr=DSA_GetItemPtr@8 @323 NONAME
+DSA_InsertItem=DSA_InsertItem@12 @324 NONAME
+DSA_SetItem=DSA_SetItem@12 @325 NONAME
+DSA_DeleteItem=DSA_DeleteItem@8 @326 NONAME
+DSA_DeleteAllItems=DSA_DeleteAllItems@4 @327 NONAME
+DPA_Create=DPA_Create@4 @328 NONAME
+DPA_Destroy=DPA_Destroy@4 @329 NONAME
+DPA_Grow=DPA_Grow@8 @330 NONAME
+DPA_Clone=DPA_Clone@8 @331 NONAME
+DPA_GetPtr=DPA_GetPtr@8 @332 NONAME
+DPA_GetPtrIndex=DPA_GetPtrIndex@8 @333 NONAME
+DPA_InsertPtr=DPA_InsertPtr@12 @334 NONAME
+DPA_SetPtr=DPA_SetPtr@12 @335 NONAME
+DPA_DeletePtr=DPA_DeletePtr@8 @336 NONAME
+DPA_DeleteAllPtrs=DPA_DeleteAllPtrs@4 @337 NONAME
+DPA_Sort=DPA_Sort@12 @338 NONAME
+DPA_Search=DPA_Search@24 @339 NONAME
+DPA_CreateEx=DPA_CreateEx@8 @340 NONAME
+SendNotify=SendNotify@16 @341 NONAME
+SendNotifyEx=SendNotifyEx@20 @342 NONAME
+StrChrA=StrChrA@8 @350 NONAME
+StrRChrA=StrRChrA@12 @351 NONAME
+StrCmpNA=StrCmpNA@12 @352 NONAME
+StrCmpNIA=StrCmpNIA@12 @353 NONAME
+StrStrA=StrStrA@8 @354 NONAME
+StrStrIA=StrStrIA@8 @355 NONAME
+StrCSpnA=StrCSpnA@8 @356 NONAME
+StrToIntA=StrToIntA@4 @357 NONAME
+StrChrW=StrChrW@8 @358 NONAME
+StrRChrW=StrRChrW@12 @359 NONAME
+StrCmpNW=StrCmpNW@12 @360 NONAME
+StrCmpNIW=StrCmpNIW@12 @361 NONAME
+StrStrW=StrStrW@8 @362 NONAME
+StrStrIW=StrStrIW@8 @363 NONAME
+StrSpnW=StrSpnW@8 @364 NONAME
+StrToIntW=StrToIntW@4 @365 NONAME
+SmoothScrollWindow=SmoothScrollWindow@4 @382 NONAME
+DPA_EnumCallback=DPA_EnumCallback@12 @385 NONAME
+DPA_DestroyCallback=DPA_DestroyCallback@12 @386 NONAME
+DSA_EnumCallback=DSA_EnumCallback@12 @387 NONAME
+DSA_DestroyCallback=DSA_DestroyCallback@12 @388 NONAME
+CreateMRUListW=CreateMRUListW@4 @400 NONAME
+AddMRUStringW=AddMRUStringW@8 @401 NONAME
+FindMRUStringW=FindMRUStringW@12 @402 NONAME
+EnumMRUListW=EnumMRUListW@16 @403 NONAME
+CreateMRUListLazyW=CreateMRUListLazyW@16 @404 NONAME
+SetWindowSubclass=SetWindowSubclass@16 @410
+GetWindowSubclass=GetWindowSubclass@16 @411
+RemoveWindowSubclass=RemoveWindowSubclass@12 @412
+DefSubclassProc=DefSubclassProc@16 @413
+DrawTextWrap=DrawTextWrap@20 @415 NONAME
+ExtTextOutWrap=ExtTextOutWrap@32 @417 NONAME
+GetTextExtentPointWrap=GetTextExtentPointWrap@16 @419 NONAME
+CreatePropertySheetPage=CreatePropertySheetPageA@4 @12
+CreatePropertySheetPageA=CreatePropertySheetPageA@4 @18
+CreatePropertySheetPageW=CreatePropertySheetPageW@4 @19
+CreateStatusWindow=CreateStatusWindowA@16 @20
+CreateStatusWindowW=CreateStatusWindowW@16 @21
+CreateToolbarEx=CreateToolbarEx@52 @22
+DestroyPropertySheetPage=DestroyPropertySheetPage@4 @23
+DllGetVersion=COMCTL32_DllGetVersion@4 @24
+DllInstall=COMCTL32_DllInstall@8 @25
+DrawStatusText=DrawStatusTextA@16 @26
+DrawStatusTextW=DrawStatusTextW@16 @27
+FlatSB_EnableScrollBar=FlatSB_EnableScrollBar@12 @28
+FlatSB_GetScrollInfo=FlatSB_GetScrollInfo@12 @29
+FlatSB_GetScrollPos=FlatSB_GetScrollPos@8 @30
+FlatSB_GetScrollProp=FlatSB_GetScrollProp@12 @31
+FlatSB_GetScrollRange=FlatSB_GetScrollRange@16 @32
+FlatSB_SetScrollInfo=FlatSB_SetScrollInfo@16 @33
+FlatSB_SetScrollPos=FlatSB_SetScrollPos@16 @34
+FlatSB_SetScrollProp=FlatSB_SetScrollProp@16 @35
+FlatSB_SetScrollRange=FlatSB_SetScrollRange@20 @36
+FlatSB_ShowScrollBar=FlatSB_ShowScrollBar@12 @37
+GetMUILanguage=GetMUILanguage@0 @38
+ImageList_Add=ImageList_Add@12 @39
+ImageList_AddIcon=ImageList_AddIcon@8 @40
+ImageList_AddMasked=ImageList_AddMasked@12 @41
+ImageList_BeginDrag=ImageList_BeginDrag@16 @42
+ImageList_Copy=ImageList_Copy@20 @43
+ImageList_Create=ImageList_Create@20 @44
+ImageList_Destroy=ImageList_Destroy@4 @45
+ImageList_DragEnter=ImageList_DragEnter@12 @46
+ImageList_DragLeave=ImageList_DragLeave@4 @47
+ImageList_DragMove=ImageList_DragMove@8 @48
+ImageList_DragShowNolock=ImageList_DragShowNolock@4 @49
+ImageList_Draw=ImageList_Draw@24 @50
+ImageList_DrawEx=ImageList_DrawEx@40 @51
+ImageList_DrawIndirect=ImageList_DrawIndirect@4 @52
+ImageList_Duplicate=ImageList_Duplicate@4 @53
+ImageList_EndDrag=ImageList_EndDrag@0 @54
+ImageList_GetBkColor=ImageList_GetBkColor@4 @55
+ImageList_GetDragImage=ImageList_GetDragImage@8 @56
+ImageList_GetFlags=ImageList_GetFlags@4 @57
+ImageList_GetIcon=ImageList_GetIcon@12 @58
+ImageList_GetIconSize=ImageList_GetIconSize@12 @59
+ImageList_GetImageCount=ImageList_GetImageCount@4 @60
+ImageList_GetImageInfo=ImageList_GetImageInfo@12 @61
+ImageList_GetImageRect=ImageList_GetImageRect@12 @62
+ImageList_LoadImage=ImageList_LoadImageA@28 @63
+ImageList_LoadImageA=ImageList_LoadImageA@28 @64
+ImageList_LoadImageW=ImageList_LoadImageW@28 @65
+ImageList_Merge=ImageList_Merge@24 @66
+ImageList_Read=ImageList_Read@4 @67
+ImageList_Remove=ImageList_Remove@8 @68
+ImageList_Replace=ImageList_Replace@16 @69
+ImageList_ReplaceIcon=ImageList_ReplaceIcon@12 @70
+ImageList_SetBkColor=ImageList_SetBkColor@8 @75
+ImageList_SetDragCursorImage=ImageList_SetDragCursorImage@16 @76
+ImageList_SetFilter=ImageList_SetFilter@12 @77
+ImageList_SetFlags=ImageList_SetFlags@8 @78
+ImageList_SetIconSize=ImageList_SetIconSize@12 @79
+ImageList_SetImageCount=ImageList_SetImageCount@8 @80
+ImageList_SetOverlayImage=ImageList_SetOverlayImage@12 @81
+ImageList_Write=ImageList_Write@8 @82
+InitCommonControlsEx=InitCommonControlsEx@4 @83
+InitMUILanguage=InitMUILanguage@4 @84
+InitializeFlatSB=InitializeFlatSB@4 @85
+PropertySheet=PropertySheetA@4 @86
+PropertySheetA=PropertySheetA@4 @87
+PropertySheetW=PropertySheetW@4 @88
+UninitializeFlatSB=UninitializeFlatSB@4 @89
+_TrackMouseEvent=_TrackMouseEvent@4 @90
index defdda3..3d7f5c2 100644 (file)
-/******************************************************************************\r
- *\r
- * Common definitions (resource ids and global variables)\r
- *\r
- * Copyright 1999 Thuy Nguyen\r
- * Copyright 1999 Eric Kohl\r
- * Copyright 2002 Dimitrie O. Paun\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-\r
-#ifndef __WINE_COMCTL32_H\r
-#define __WINE_COMCTL32_H\r
-\r
-#ifndef RC_INVOKED\r
-#include <stdarg.h>\r
-#endif\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "wingdi.h"\r
-#include "winuser.h"\r
-#include "winnls.h"\r
-#include "commctrl.h"\r
-\r
-extern HMODULE COMCTL32_hModule;\r
-extern HBRUSH  COMCTL32_hPattern55AABrush;\r
-\r
-/* Property sheet / Wizard */\r
-#define IDD_PROPSHEET 1006\r
-#define IDD_WIZARD    1020\r
-\r
-#define IDC_TABCONTROL   12320\r
-#define IDC_APPLY_BUTTON 12321\r
-#define IDC_BACK_BUTTON  12323\r
-#define IDC_NEXT_BUTTON  12324\r
-#define IDC_FINISH_BUTTON 12325\r
-#define IDC_SUNKEN_LINE   12326\r
-\r
-#define IDS_CLOSE        4160\r
-\r
-/* Toolbar customization dialog */\r
-#define IDD_TBCUSTOMIZE     200\r
-\r
-#define IDC_AVAILBTN_LBOX   201\r
-#define IDC_RESET_BTN       202\r
-#define IDC_TOOLBARBTN_LBOX 203\r
-#define IDC_REMOVE_BTN      204\r
-#define IDC_HELP_BTN        205\r
-#define IDC_MOVEUP_BTN      206\r
-#define IDC_MOVEDN_BTN      207\r
-\r
-#define IDS_SEPARATOR      1024\r
-\r
-/* Toolbar imagelist bitmaps */\r
-#define IDB_STD_SMALL       120\r
-#define IDB_STD_LARGE       121\r
-#define IDB_VIEW_SMALL      124\r
-#define IDB_VIEW_LARGE      125\r
-#define IDB_HIST_SMALL      130\r
-#define IDB_HIST_LARGE      131\r
-\r
-\r
-/* Month calendar month menu popup */\r
-#define IDD_MCMONTHMENU     300\r
-\r
-#define IDM_JAN                                301\r
-#define IDM_FEB                                302\r
-#define IDM_MAR                                303\r
-#define IDM_APR                                304\r
-#define IDM_MAY                                305\r
-#define IDM_JUN                                306\r
-#define IDM_JUL                                307\r
-#define IDM_AUG                                308\r
-#define IDM_SEP                                309\r
-#define IDM_OCT                                310\r
-#define IDM_NOV                                311\r
-#define IDM_DEC                                312\r
-\r
-#define IDM_TODAY                      4163\r
-#define IDM_GOTODAY                    4164\r
-\r
-/* Treeview Checkboxes */\r
-\r
-#define IDT_CHECK        401\r
-\r
-\r
-/* Header cursors */\r
-#define IDC_DIVIDER                     106\r
-#define IDC_DIVIDEROPEN                 107\r
-\r
-\r
-/* DragList icon */\r
-#define IDI_DRAGARROW                   150\r
-\r
-\r
-/* HOTKEY internal strings */\r
-#define HKY_NONE                        2048\r
-\r
-typedef struct\r
-{\r
-    COLORREF clrBtnHighlight;       /* COLOR_BTNHIGHLIGHT                  */\r
-    COLORREF clrBtnShadow;          /* COLOR_BTNSHADOW                     */\r
-    COLORREF clrBtnText;            /* COLOR_BTNTEXT                       */\r
-    COLORREF clrBtnFace;            /* COLOR_BTNFACE                       */\r
-    COLORREF clrHighlight;          /* COLOR_HIGHLIGHT                     */\r
-    COLORREF clrHighlightText;      /* COLOR_HIGHLIGHTTEXT                 */\r
-    COLORREF clr3dHilight;          /* COLOR_3DHILIGHT                     */\r
-    COLORREF clr3dShadow;           /* COLOR_3DSHADOW                      */\r
-    COLORREF clr3dDkShadow;         /* COLOR_3DDKSHADOW                    */\r
-    COLORREF clr3dFace;             /* COLOR_3DFACE                        */\r
-    COLORREF clrWindow;             /* COLOR_WINDOW                        */\r
-    COLORREF clrWindowText;         /* COLOR_WINDOWTEXT                    */\r
-    COLORREF clrGrayText;           /* COLOR_GREYTEXT                      */\r
-    COLORREF clrActiveCaption;      /* COLOR_ACTIVECAPTION                 */\r
-    COLORREF clrInfoBk;             /* COLOR_INFOBK                        */\r
-    COLORREF clrInfoText;           /* COLOR_INFOTEXT                      */\r
-} COMCTL32_SysColor;\r
-\r
-extern COMCTL32_SysColor  comctl32_color;\r
-\r
-/* Internal function */\r
-HWND COMCTL32_CreateToolTip (HWND);\r
-VOID COMCTL32_RefreshSysColors(void);\r
-INT  Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen);\r
-BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc);\r
-\r
-#define COMCTL32_VERSION_MINOR 80\r
-#define WINE_FILEVERSION 5, COMCTL32_VERSION_MINOR, 0, 0\r
-#define WINE_FILEVERSIONSTR "5.80"\r
-\r
-/* Our internal stack structure of the window procedures to subclass */\r
-typedef struct\r
-{\r
-   struct {\r
-      SUBCLASSPROC subproc;\r
-      UINT_PTR id;\r
-      DWORD_PTR ref;\r
-   } SubclassProcs[31];\r
-   int stackpos;\r
-   int stacknum;\r
-   int stacknew;\r
-   WNDPROC origproc;\r
-} SUBCLASS_INFO, *LPSUBCLASS_INFO;\r
-\r
-/* undocumented functions */\r
-\r
-LPVOID WINAPI Alloc (DWORD);\r
-LPVOID WINAPI ReAlloc (LPVOID, DWORD);\r
-BOOL   WINAPI Free (LPVOID);\r
-DWORD  WINAPI GetSize (LPVOID);\r
-\r
-INT  WINAPI Str_GetPtrA (LPCSTR, LPSTR, INT);\r
-INT  WINAPI Str_GetPtrW (LPCWSTR, LPWSTR, INT);\r
-\r
-INT  WINAPI DPA_GetPtrIndex (const HDPA, LPVOID);\r
-BOOL WINAPI DPA_Grow (const HDPA, INT);\r
-\r
-#define DPAM_NOSORT             0x0001\r
-#define DPAM_INSERT             0x0004\r
-#define DPAM_DELETE             0x0008\r
-\r
-typedef PVOID (CALLBACK *PFNDPAMERGE)(DWORD,PVOID,PVOID,LPARAM);\r
-BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, PFNDPAMERGE, LPARAM);\r
-\r
-#define DPA_GetPtrCount(hdpa)  (*(INT*)(hdpa))\r
-\r
-/*\r
- * The following is ReactOS specific, present in Wine's commctrl.h\r
- */\r
-\r
-#ifdef __REACTOS__\r
-#define TBSTYLE_EX_UNDOC1 0x04\r
-\r
-/* Undocumented messages in Toolbar */\r
-#define TB_UNKWN45D    (WM_USER+93)\r
-#define TB_UNKWN45E    (WM_USER+94)\r
-#define TB_UNKWN460    (WM_USER+96)\r
-#define TB_UNKWN463    (WM_USER+99)\r
-#define TB_UNKWN464    (WM_USER+100)\r
-\r
-#define Header_GetItemA(w,i,d) (BOOL)SendMessageA((w),HDM_GETITEMA,(WPARAM)(i),(LPARAM)(HDITEMA*)(d))\r
-#define Header_GetItemW(w,i,d) (BOOL)SendMessageW((w),HDM_GETITEMW,(WPARAM)(i),(LPARAM)(HDITEMW*)(d))\r
-#define Header_SetItemA(w,i,d) (BOOL)SendMessageA((w),HDM_SETITEMA,(WPARAM)(i),(LPARAM)(const HDITEMA*)(d))\r
-#define Header_SetItemW(w,i,d) (BOOL)SendMessageW((w),HDM_SETITEMW,(WPARAM)(i),(LPARAM)(const HDITEMW*)(d))\r
-#define ListView_FindItemA(w,p,i) (INT)SendMessageA((w),LVM_FINDITEMA,(WPARAM)(p),(LPARAM)(LVFINDINFOA*)(i))\r
-#define ListView_FindItemW(w,p,i) (INT)SendMessageW((w),LVM_FINDITEMW,(WPARAM)(p),(LPARAM)(LVFINDINFOW*)(i))\r
-\r
-#define FLATSB_CLASSA "flatsb_class32"\r
-\r
-/* FIXME: Rebar definition hack, should be patched in Wine */\r
-#undef RB_GETBANDINFO\r
-#define RB_GETBANDINFO (WM_USER+5)   /* just for compatibility */\r
-\r
-/* Property sheet Wizard 97 styles */\r
-#define        PSH_WIZARD97_OLD 0x2000\r
-#define        PSH_WIZARD97_NEW 0x1000000\r
-#endif\r
-\r
-#endif  /* __WINE_COMCTL32_H */\r
+/******************************************************************************
+ *
+ * Common definitions (resource ids and global variables)
+ *
+ * Copyright 1999 Thuy Nguyen
+ * Copyright 1999 Eric Kohl
+ * Copyright 2002 Dimitrie O. Paun
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_COMCTL32_H
+#define __WINE_COMCTL32_H
+
+#ifndef RC_INVOKED
+#include <stdarg.h>
+#endif
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+#include "commctrl.h"
+
+extern HMODULE COMCTL32_hModule;
+extern HBRUSH  COMCTL32_hPattern55AABrush;
+
+/* Property sheet / Wizard */
+#define IDD_PROPSHEET 1006
+#define IDD_WIZARD    1020
+
+#define IDC_TABCONTROL   12320
+#define IDC_APPLY_BUTTON 12321
+#define IDC_BACK_BUTTON  12323
+#define IDC_NEXT_BUTTON  12324
+#define IDC_FINISH_BUTTON 12325
+#define IDC_SUNKEN_LINE   12326
+
+#define IDS_CLOSE        4160
+
+/* Toolbar customization dialog */
+#define IDD_TBCUSTOMIZE     200
+
+#define IDC_AVAILBTN_LBOX   201
+#define IDC_RESET_BTN       202
+#define IDC_TOOLBARBTN_LBOX 203
+#define IDC_REMOVE_BTN      204
+#define IDC_HELP_BTN        205
+#define IDC_MOVEUP_BTN      206
+#define IDC_MOVEDN_BTN      207
+
+#define IDS_SEPARATOR      1024
+
+/* Toolbar imagelist bitmaps */
+#define IDB_STD_SMALL       120
+#define IDB_STD_LARGE       121
+#define IDB_VIEW_SMALL      124
+#define IDB_VIEW_LARGE      125
+#define IDB_HIST_SMALL      130
+#define IDB_HIST_LARGE      131
+
+
+/* Month calendar month menu popup */
+#define IDD_MCMONTHMENU     300
+
+#define IDM_JAN                                301
+#define IDM_FEB                                302
+#define IDM_MAR                                303
+#define IDM_APR                                304
+#define IDM_MAY                                305
+#define IDM_JUN                                306
+#define IDM_JUL                                307
+#define IDM_AUG                                308
+#define IDM_SEP                                309
+#define IDM_OCT                                310
+#define IDM_NOV                                311
+#define IDM_DEC                                312
+
+#define IDM_TODAY                      4163
+#define IDM_GOTODAY                    4164
+
+/* Treeview Checkboxes */
+
+#define IDT_CHECK        401
+
+
+/* Header cursors */
+#define IDC_DIVIDER                     106
+#define IDC_DIVIDEROPEN                 107
+
+
+/* DragList icon */
+#define IDI_DRAGARROW                   150
+
+
+/* HOTKEY internal strings */
+#define HKY_NONE                        2048
+
+typedef struct
+{
+    COLORREF clrBtnHighlight;       /* COLOR_BTNHIGHLIGHT                  */
+    COLORREF clrBtnShadow;          /* COLOR_BTNSHADOW                     */
+    COLORREF clrBtnText;            /* COLOR_BTNTEXT                       */
+    COLORREF clrBtnFace;            /* COLOR_BTNFACE                       */
+    COLORREF clrHighlight;          /* COLOR_HIGHLIGHT                     */
+    COLORREF clrHighlightText;      /* COLOR_HIGHLIGHTTEXT                 */
+    COLORREF clr3dHilight;          /* COLOR_3DHILIGHT                     */
+    COLORREF clr3dShadow;           /* COLOR_3DSHADOW                      */
+    COLORREF clr3dDkShadow;         /* COLOR_3DDKSHADOW                    */
+    COLORREF clr3dFace;             /* COLOR_3DFACE                        */
+    COLORREF clrWindow;             /* COLOR_WINDOW                        */
+    COLORREF clrWindowText;         /* COLOR_WINDOWTEXT                    */
+    COLORREF clrGrayText;           /* COLOR_GREYTEXT                      */
+    COLORREF clrActiveCaption;      /* COLOR_ACTIVECAPTION                 */
+    COLORREF clrInfoBk;             /* COLOR_INFOBK                        */
+    COLORREF clrInfoText;           /* COLOR_INFOTEXT                      */
+} COMCTL32_SysColor;
+
+extern COMCTL32_SysColor  comctl32_color;
+
+/* Internal function */
+HWND COMCTL32_CreateToolTip (HWND);
+VOID COMCTL32_RefreshSysColors(void);
+INT  Str_GetPtrWtoA (LPCWSTR lpSrc, LPSTR lpDest, INT nMaxLen);
+BOOL Str_SetPtrAtoW (LPWSTR *lppDest, LPCSTR lpSrc);
+
+#define COMCTL32_VERSION_MINOR 80
+#define WINE_FILEVERSION 5, COMCTL32_VERSION_MINOR, 0, 0
+#define WINE_FILEVERSIONSTR "5.80"
+
+/* Our internal stack structure of the window procedures to subclass */
+typedef struct
+{
+   struct {
+      SUBCLASSPROC subproc;
+      UINT_PTR id;
+      DWORD_PTR ref;
+   } SubclassProcs[31];
+   int stackpos;
+   int stacknum;
+   int stacknew;
+   WNDPROC origproc;
+} SUBCLASS_INFO, *LPSUBCLASS_INFO;
+
+/* undocumented functions */
+
+LPVOID WINAPI Alloc (DWORD);
+LPVOID WINAPI ReAlloc (LPVOID, DWORD);
+BOOL   WINAPI Free (LPVOID);
+DWORD  WINAPI GetSize (LPVOID);
+
+INT  WINAPI Str_GetPtrA (LPCSTR, LPSTR, INT);
+INT  WINAPI Str_GetPtrW (LPCWSTR, LPWSTR, INT);
+
+INT  WINAPI DPA_GetPtrIndex (const HDPA, LPVOID);
+BOOL WINAPI DPA_Grow (const HDPA, INT);
+
+#define DPAM_NOSORT             0x0001
+#define DPAM_INSERT             0x0004
+#define DPAM_DELETE             0x0008
+
+typedef PVOID (CALLBACK *PFNDPAMERGE)(DWORD,PVOID,PVOID,LPARAM);
+BOOL WINAPI DPA_Merge (const HDPA, const HDPA, DWORD, PFNDPACOMPARE, PFNDPAMERGE, LPARAM);
+
+#define DPA_GetPtrCount(hdpa)  (*(INT*)(hdpa))
+
+/*
+ * The following is ReactOS specific, present in Wine's commctrl.h
+ */
+
+#ifdef __REACTOS__
+#define TBSTYLE_EX_UNDOC1 0x04
+
+/* Undocumented messages in Toolbar */
+#define TB_UNKWN45D    (WM_USER+93)
+#define TB_UNKWN45E    (WM_USER+94)
+#define TB_UNKWN460    (WM_USER+96)
+#define TB_UNKWN463    (WM_USER+99)
+#define TB_UNKWN464    (WM_USER+100)
+
+#define Header_GetItemA(w,i,d) (BOOL)SendMessageA((w),HDM_GETITEMA,(WPARAM)(i),(LPARAM)(HDITEMA*)(d))
+#define Header_GetItemW(w,i,d) (BOOL)SendMessageW((w),HDM_GETITEMW,(WPARAM)(i),(LPARAM)(HDITEMW*)(d))
+#define Header_SetItemA(w,i,d) (BOOL)SendMessageA((w),HDM_SETITEMA,(WPARAM)(i),(LPARAM)(const HDITEMA*)(d))
+#define Header_SetItemW(w,i,d) (BOOL)SendMessageW((w),HDM_SETITEMW,(WPARAM)(i),(LPARAM)(const HDITEMW*)(d))
+#define ListView_FindItemA(w,p,i) (INT)SendMessageA((w),LVM_FINDITEMA,(WPARAM)(p),(LPARAM)(LVFINDINFOA*)(i))
+#define ListView_FindItemW(w,p,i) (INT)SendMessageW((w),LVM_FINDITEMW,(WPARAM)(p),(LPARAM)(LVFINDINFOW*)(i))
+
+#define FLATSB_CLASSA "flatsb_class32"
+
+/* FIXME: Rebar definition hack, should be patched in Wine */
+#undef RB_GETBANDINFO
+#define RB_GETBANDINFO (WM_USER+5)   /* just for compatibility */
+
+/* Property sheet Wizard 97 styles */
+#define        PSH_WIZARD97_OLD 0x2000
+#define        PSH_WIZARD97_NEW 0x1000000
+#endif
+
+#endif  /* __WINE_COMCTL32_H */
index 0e5095f..7be0f09 100644 (file)
@@ -1,41 +1,41 @@
-/* \r
- * FIXME:\r
- * Can't use Wine's resource script because it doesn't work with windres.\r
- */\r
-\r
-/*#include "rsrc.rc"*/\r
-\r
-#include <windows.h>\r
-#include "comctl32.h"\r
-#include "wine/wine_common_ver.rc"\r
-\r
-LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL\r
-\r
-IDB_STD_SMALL BITMAP "res/idb_std_small.bmp"\r
-IDB_STD_LARGE BITMAP "res/idb_std_large.bmp"\r
-IDB_VIEW_SMALL BITMAP "res/idb_view_small.bmp"\r