⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stastrip.c

📁 英文版的 想要的话可以下载了 为大家服务
💻 C
📖 第 1 页 / 共 2 页
字号:
 * IStringFromID
 *
 * Purpose:
 *  Performs a binary search in a STATMESSAGEMAP array looking for
 *  a specific item ID returning the string ID for that item.
 *
 * Parameters:
 *  pSMM            PSTATMESSAGEMAP to search
 *  cItems          USHORT size of the map in elements
 *  uID             USHORT item ID to locate.
 *
 * Return Value:
 *  UINT            String ID associated with wItem.
 */

UINT IStringFromID(PSTATMESSAGEMAP pSMM, USHORT cItems, USHORT uID)
    {
    UINT        iLow =0;
    UINT        iHigh=cItems-1;
    UINT        iMid;

    while (TRUE)
        {
        iMid=(iLow+iHigh) >> 1;

        if (uID < pSMM[iMid].uID)
            iHigh=iMid-1;
        else
            {
            if (uID > pSMM[iMid].uID)
                iLow=iMid+1;
            else
                break;    //Equality
            }

        if (iHigh < iLow)
            break;
        }

    return pSMM[iMid].idsMsg;
    }




/*
 * StatStripMessageMap
 *
 * Purpose:
 *  Initializes the message mappings in the StatStrip for subsequent
 *  use with StatMessageMenuSelect.  If this function is called more
 *  than once then any previous initialization is cleaned up so
 *  previous message IDs will then be invalid.
 *
 *  The total number of messages is inferred by (idsMax-idsMin+1).
 *  The maximum number of popup menu items we'll hold is inferred by
 *  (uIDPopupMax-uIDPopupMin+1).
 *
 * Parameters:
 *  hWnd            HWND of the StatStrip control.
 *  hWndOwner       HWND of the window owning menus.
 *  hInst           HINSTANCE of the app from which to load resources
 *  uIDRMap         UINT identifying a resource mapping ID values
 *                  to string ID values.
 *  idsMin          UINT specifying the lowest string ID to load.
 *  idsMax          UINT specifying the hightest string ID to load.
 *  cchMax          UINT maximum string length.
 *  uIDPopupMin     USHORT lowest ID to assign to popup menus.
 *  uIDPopupMax     USHORT highest ID to assign to popup menus.
 *  uIDStatic       USHORT ID for the quiescent message.
 *  uIDBlank        USHORT ID for a blank message.
 *  uIDSysMenu      USHORT ID for the system menu.
 *
 * Return Value:
 *  BOOL            TRUE if the function was successful, FALSE
 *                  otherwise.
 */

BOOL WINAPI StatStripMessageMap(HWND hWnd, HWND hWndOwner
    , HINSTANCE hInst , UINT uIDRMap, UINT idsMin, UINT idsMax
    , UINT cchMax, USHORT uIDPopupMin, USHORT uIDPopupMax
    , USHORT uIDStatic, USHORT uIDBlank, USHORT uIDSysMenu)
    {
    PSTATSTRIP      pST;
    HMENU           hMenu;
    HRSRC           hRes;
    UINT            i;
    USHORT          uID;

   #ifdef WIN32
    DWORD           cbRes;
    DWORD           dwPrevProt;
   #endif

    if (!IsWindow(hWnd))
        return FALSE;

    pST=(PSTATSTRIP)GetWindowLong(hWnd, STATWL_STRUCTURE);

    if (NULL==pST)
        return FALSE;

    //Parameter validation
    if (NULL==hInst || idsMax < idsMin || uIDPopupMax < uIDPopupMin)
        return FALSE;

    //Clean ourselves out if we've already initialized.
    if (pST->fMapped)
        StatStripClean(pST, FALSE);

    pST->hWndOwner  =hWndOwner;

    pST->idsMin     =idsMin;
    pST->idsMax     =idsMax;
    pST->cMessages  =(USHORT)(idsMax-idsMin+1);

    pST->uIDPopupMin=uIDPopupMin;
    pST->uIDPopupMax=uIDPopupMax;
    pST->cPopups    =(USHORT)(uIDPopupMax-uIDPopupMin+1);

    pST->uIDStatic  =uIDStatic;
    pST->uIDBlank   =uIDBlank;
    pST->uIDSysMenu =uIDSysMenu;

    //Load the STATMESSAGEMAP array from our resources.
    hRes=FindResource(hInst, MAKEINTRESOURCE(uIDRMap), RT_RCDATA);

    if (NULL==hRes)
        return FALSE;


    pST->hMemSMM=LoadResource(hInst, hRes);

    if (NULL==pST->hMemSMM)
        return FALSE;

    pST->pSMM=(PSTATMESSAGEMAP)LockResource(pST->hMemSMM);

    if (NULL==pST->pSMM)
        {
        StatStripClean(pST, FALSE);
        return FALSE;
        }

   #ifdef WIN32
    /*
     * In Win32 resource pages are read-only when loaded.
     * Change to read-write for the purposes of sorting
     * initially.
     */
    cbRes=SizeofResource(hInst, hRes);
    VirtualProtect(pST->pSMM, cbRes, PAGE_READWRITE, &dwPrevProt);
   #endif

    //Sort these for binary search lookup.
    StatMessageMapSort(pST->pSMM, pST->cMessages);

   #ifdef WIN32
    VirtualProtect(pST->pSMM, cbRes, dwPrevProt, &dwPrevProt);
   #endif

    //Allocate space for string pointers
    pST->ppsz=(LPTSTR *)LocalAlloc(LPTR
        , sizeof(LPTSTR)*pST->cMessages);

    if (NULL==pST->ppsz)
        {
        StatStripClean(pST, FALSE);
        return FALSE;
        }

    //Load the stringtable for messages.
    pST->hMemSzStat=HStringCache(hInst, idsMin, idsMax, cchMax
        , pST->ppsz);

    if (NULL==pST->hMemSzStat)
        {
        StatStripClean(pST, FALSE);
        return FALSE;
        }

    //Allocate an array of POPUPMENUMAP structures
    pST->pPMM=(PPOPUPMENUMAP)(void *)LocalAlloc(LPTR
        , sizeof(POPUPMENUMAP)*pST->cPopups);

    if (NULL==pST->pPMM)
        {
        StatStripClean(pST, FALSE);
        return FALSE;
        }

    //Initialize the array mapping popup menus to specific IDs.
    uID=uIDPopupMin;
    hMenu=GetMenu(hWndOwner);

    for (i=0; i < pST->cPopups; i++)
        {
        pST->pPMM[i].hMenu=GetSubMenu(hMenu, i);
        pST->pPMM[i].uID  =uID++;
        }

    pST->fMapped=TRUE;
    return TRUE;
    }







/*
 * StatStripClean
 *
 * Purpose:
 *  Cleans out any allocations in a STATSTRIP.
 *
 * Parameters:
 *  pST             PSTATSTRIP to clean
 *  fIncludeFont    BOOL indicates if we're to also clean the font.
 *                  This is FALSE from StatMessageMap, TRUE from
 *                  WM_DESTROY.
 *
 * Return Value:
 *  None
 */

void StatStripClean(PSTATSTRIP pST, BOOL fIncludeFont)
    {
    //Free up anything from StatMessageMap
    if (NULL!=pST->pPMM)
        {
        LocalFree((HLOCAL)(UINT)(LONG)pST->pPMM);
        pST->pPMM=NULL;
        }

    if (NULL!=pST->ppsz)
        {
        LocalFree((HLOCAL)(UINT)(LONG)pST->ppsz);
        pST->ppsz=NULL;
        }

    if (NULL!=pST->hMemSzStat)
        {
        HStringCacheFree(pST->hMemSzStat);
        pST->hMemSzStat=NULL;
        }

    if (NULL!=pST->pSMM)
        {
       #ifndef WIN32
        UnlockResource(pST->hMemSMM);
       #endif
        pST->pSMM=NULL;
        }

    if (NULL!=pST->hMemSMM)
        {
        FreeResource(pST->hMemSMM);
        pST->hMemSMM=NULL;
        }

    //Delete the old font only if we own it.
    if (fIncludeFont)
        {
        if (NULL!=pST->hFont && pST->fMyFont)
            {
            DeleteObject(pST->hFont);
            pST->hFont=NULL;
            }
        }

    return;
    }





/*
 * HStringCache
 *
 * Purpose:
 *  Allocates memory and reads a stringtable into that memory.
 *  Pointers to the strings in the memory are then stored at ppsz
 *  which is assumed to be (idsMax-idsMin+1) strings long.
 *
 * Parameters:
 *  hInst           HINSTANCE of the application
 *  idsMin          UINT string index to start loading
 *  idsMax          UINT maximum string index in this table.
 *  cchMax          UINT length of the longest string in TCHARs.
 *  ppsz            LPTSTR * to an array in which to store pointers.
 *
 * Return Value:
 *  HGLOBAL         Handle to the memory.  NULL if memory could
 *                  not be allocated.
 */

HGLOBAL HStringCache(HINSTANCE hInst, UINT idsMin, UINT idsMax
    , UINT cchMax, LPTSTR *ppsz)
    {
    HANDLE      hMem;
    LPTSTR      pch;
    UINT        cchUsed=0;
    UINT        cch;
    UINT        i, cStrings;

    cStrings=idsMax-idsMin+1;
    hMem=GlobalAlloc(GHND, cStrings * cchMax * sizeof(TCHAR));

    if (NULL!=hMem)
        {
        pch=GlobalLock(hMem);

        /*
         * Load the strings into the memory and retain the specific
         * pointer to that string.
         */
        for (i=0; i < cStrings; i++)
            {
            cch=LoadString(hInst, i+idsMin, (LPTSTR)(pch+cchUsed)
                , cchMax-1);
            ppsz[i]=(LPTSTR)(pch+cchUsed);

            /*
             * Add one char to cch to include a NULL.  The memory
             * was ZEROINITed on allocation so by skipping a TCHAR
             * we get the NULL.
             */
            cchUsed+=cch+sizeof(TCHAR);
            }

        /*
         * Memory is locked for the duration of the app.  Don't
         * bother reallocating since we might have to recalc
         * all the pointers to the strings again.
         */
        }

    return hMem;
    }





/*
 * HStringCacheFree
 *
 * Purpose:
 *  Frees up any memory associated with the string cache from
 *  HStringCache.
 *
 * Parameters:
 *  hMem            HGLOBAL to the memory containing the cahce.
 *
 * Return Value:
 *  None
 */

void HStringCacheFree(HGLOBAL hMem)
    {
    if (NULL!=hMem)
        {
        GlobalUnlock(hMem);
        GlobalFree(hMem);
        }
    return;
    }





/*
 * StatMessageMapSort
 *
 * Purpose:
 *  Performs a selection sort on the STATMESSAGEMAP array that we
 *  load from our resource.  Since we expect that the data is
 *  partially sorted (we tend to place things in resources in groups
 *  of seqential values), since the number of messages is usually
 *  < 200, and since we're in startup (which takes a long time
 *  anyway), selection sort is a better choice to implement over
 *  qsort saving much code.
 *
 * Parameters:
 *  pSMM            PSTATMESSAGEMAP to sort
 *  n               USHORT number of elements in the array.
 *
 * Return Value:
 *  None
 */

void StatMessageMapSort(PSTATMESSAGEMAP pSMM, USHORT n)
    {
    USHORT          i, j, k;
    STATMESSAGEMAP  smm;

    for (j=0; j < (UINT)(n-1); j++)
        {
        k=j;
        smm.uID   =pSMM[j].uID;
        smm.idsMsg=pSMM[j].idsMsg;

        for (i=j+1; i < (UINT)n; i++)
            {
            if (pSMM[i].uID < smm.uID)
                {
                smm.uID   =pSMM[i].uID;
                smm.idsMsg=pSMM[i].idsMsg;
                k=i;
                }
            }

        smm.uID       =pSMM[j].uID;
        smm.idsMsg    =pSMM[j].idsMsg;
        pSMM[j].uID   =pSMM[k].uID;
        pSMM[j].idsMsg=pSMM[k].idsMsg;
        pSMM[k].uID   =smm.uID;
        pSMM[k].idsMsg=smm.idsMsg;
        }

    return;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -