开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

楼主: 7ian
收起左侧

[易语言纯源码] 底层核心自由的信息框-SoftModalMessageBox

    [复制链接]
结帖率:86% (12/14)
发表于 2024-6-15 17:42:58 | 显示全部楼层   广西壮族自治区南宁市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)

签到天数: 7 天

发表于 2024-6-13 04:49:00 | 显示全部楼层   江西省上饶市
这才是大咖啊。
回复 支持 反对

使用道具 举报

签到天数: 12 天

发表于 2024-6-12 15:25:28 | 显示全部楼层   山东省日照市
厉害
回复 支持 反对

使用道具 举报

结帖率:100% (5/5)
发表于 2024-6-10 07:26:44 | 显示全部楼层   江苏省盐城市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

签到天数: 8 天

发表于 2024-6-9 11:24:45 | 显示全部楼层   广东省深圳市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

签到天数: 18 天

发表于 2024-6-9 08:08:18 | 显示全部楼层   河南省平顶山市
感谢分享 赞一个 !
回复 支持 反对

使用道具 举报

签到天数: 19 天

发表于 2024-6-9 03:16:32 | 显示全部楼层   浙江省台州市
感谢分享
回复 支持 反对

使用道具 举报

发表于 2024-6-8 22:52:50 | 显示全部楼层   安徽省宿州市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

发表于 2024-6-8 18:28:56 | 显示全部楼层   河南省南阳市
学习学习
回复 支持 反对

使用道具 举报

结帖率:100% (3/3)

签到天数: 19 天

发表于 2024-6-8 01:59:11 | 显示全部楼层   广东省汕头市
[C++] 纯文本查看 复制代码
int  SoftModalMessageBox(LPMSGBOXDATA lpmb) {
    LPBYTE              lpDlgTmp;
    int                 cyIcon, cxIcon;
    int                 cxButtons;
    int                 cxMBMax;
    int                 cxText, cyText, xText;
    int                 cxBox, cyBox;
    int                 cxFoo, cxCaption;
    int                 xMB, yMB;
    HDC                 hdc;
    DWORD               wIconOrdNum;
    DWORD               wCaptionLen;
    DWORD               wTextLen;
    WORD                OrdNum[2];  // Must be an array or WORDs
    RECT                rc;
    RECT                rcWork;
    HCURSOR             hcurOld;
    DWORD               dwStyleMsg, dwStyleText;
    DWORD               dwStyleDlg;
    HWND                hwndOwner;
    LPWSTR              lpsz;
    int                 iRetVal     = 0;
    HICON               hIcon;
    HGLOBAL             hTemplate   = NULL;
    HGLOBAL             hCaption    = NULL;
    HGLOBAL             hText       = NULL;
    HINSTANCE           hInstMsg    = lpmb->hInstance;
    SIZE                size;
    HFONT               hFontOld    = NULL;

    dwStyleMsg = lpmb->dwStyle;

    if (!HIWORD(lpmb->lpszCaption)) {

        // won't ever be NULL because MessageBox sticks "Error!" in in that case
        if (hInstMsg && (hCaption = LocalAlloc(LPTR, MAX_RES_STRING * sizeof(WCHAR)))) {
            lpsz = (LPWSTR) hCaption;
            LoadString(hInstMsg, LOWORD(lpmb->lpszCaption), lpsz, MAX_RES_STRING);
        } else
            lpsz = NULL;

        lpmb->lpszCaption = lpsz ? lpsz : szEmpty;
    }

    if (!HIWORD(lpmb->lpszText)) {
        // NULL not allowed
        if (hInstMsg && (hText = LocalAlloc(LPTR, MAX_RES_STRING * sizeof(WCHAR)))) {
            lpsz = (LPWSTR) hText;
            LoadString(hInstMsg, LOWORD(lpmb->lpszText), lpsz, MAX_RES_STRING);
        } else
            lpsz = NULL;

        lpmb->lpszText = lpsz ? lpsz : szEmpty;
    }

    if ((dwStyleMsg & MB_ICONMASK) == MB_USERICON)
        hIcon = LoadIcon(hInstMsg, lpmb->lpszIcon);
    else
        hIcon = NULL;

    // For compatibility reasons, we still allow the message box to come up.
    hwndOwner = lpmb->hwndOwner;

    // For PowerBuilder4.0, we must make their messageboxes owned popups. Or, else
    // they get WM_ACTIVATEAPP and they install multiple keyboard hooks and get into
    // infinite loop later.
    // Bug #15896 -- WIN95B -- 2/17/95 -- SANKAR --
    if(!hwndOwner)
      {
        WCHAR pwszLibFileName[MAX_PATH];
        static WCHAR szPB040[] = L"PB040";  // Module name of PowerBuilder4.0
        WCHAR *pw1;

        //Is this a win3.1 or older app?
        if(GetClientInfo()->dwExpWinVer <= VER31)
          {
            if (GetModuleFileName(NULL, pwszLibFileName, sizeof(pwszLibFileName)/sizeof(WCHAR)) == 0) goto getthedc;
            pw1 = pwszLibFileName + wcslen(pwszLibFileName) - 1;
            while (pw1 > pwszLibFileName) {
                if (*pw1 == TEXT('.')) *pw1-- = 0;
                else if (*pw1 == TEXT(':')) {pw1++; break;}
                else if (*pw1 == TEXT('\\')) {pw1++; break;}
                else pw1--;
            }
            // Is this the PowerBuilder 4.0 module?
            if(!_wcsicmp(pw1, szPB040))
                hwndOwner = NtUserGetForegroundWindow(); // Make the MsgBox owned.
          }
      }
getthedc:
    // Check if we're out of cache DCs until robustness...
    if (!(hdc = NtUserGetDCEx(NULL, NULL, DCX_WINDOW | DCX_CACHE)))
        goto SMB_Exit;

    // Figure out the types and dimensions of buttons

    cxButtons = (lpmb->cButtons * gpsi->wMaxBtnSize) + ((lpmb->cButtons - 1) * XPixFromXDU(DU_BTNGAP, gpsi->cxMsgFontChar));

    // Ditto for the icon, if there is one.  If not, cxIcon & cyIcon are 0.

    if (wIconOrdNum = MB_GetIconOrdNum(dwStyleMsg)) {
        cxIcon = SYSMET(CXICON) + XPixFromXDU(DU_INNERMARGIN, gpsi->cxMsgFontChar);
        cyIcon = SYSMET(CYICON);
    } else
        cxIcon = cyIcon = 0;

    hFontOld = SelectObject(hdc, gpsi->hCaptionFont);

    // Find the max between the caption text and the buttons
    wCaptionLen = wcslen(lpmb->lpszCaption);
    GetTextExtentPoint(hdc, lpmb->lpszCaption, wCaptionLen, &size);
    cxCaption = size.cx + 2*SYSMET(CXSIZE);

    //
    // The max width of the message box is 5/8 of the work area for most
    // countries.  We will then try 6/8 and 7/8 if it won't fit.  Then
    // we will use whole screen.
    //
    CopyRect(&rcWork, &gpsi->rcWork);
    cxMBMax = MultDiv(rcWork.right - rcWork.left, 5, 8);

    cxFoo = 2*XPixFromXDU(DU_OUTERMARGIN, gpsi->cxMsgFontChar);

    SelectObject(hdc, gpsi->hMsgFont);

    //
    // If the text doesn't fit in 5/8, try 7/8 of the screen
    //
//#if defined(JAPAN) || defined(KOREA)
ReSize:
//#endif
    //
    // The message box is as big as needed to hold the caption/text/buttons,
    // but not bigger than the maximum width.
    //

    cxBox = cxMBMax - 2*SYSMET(CXFIXEDFRAME);

    /* Ask DrawText for the right cx and cy */
    rc.left     = 0;
    rc.top      = 0;
    rc.right    = cxBox - cxFoo - cxIcon;
    rc.bottom   = rcWork.bottom - rcWork.top;
    cyText = DrawTextExW(hdc, (LPWSTR)lpmb->lpszText, -1, &rc,
                DT_CALCRECT | DT_WORDBREAK | DT_EXPANDTABS |
                DT_NOPREFIX | DT_EXTERNALLEADING | DT_EDITCONTROL, NULL);
    //
    // Make sure we have enough width to hold the buttons, in addition to
    // the icon+text.  Always force the buttons.  If they don't fit, it's
    // because the working area is small.
    //
    //
    // The buttons are centered underneath the icon/text.
    //
    cxText = rc.right - rc.left + cxIcon + cxFoo;
    cxBox = min(cxBox, max(cxText, cxCaption));
    cxBox = max(cxBox, cxButtons + cxFoo);
    cxText = cxBox - cxFoo - cxIcon;

    //
    // Now we know the text width for sure.  Really calculate how high the
    // text will be.
    //
    rc.left     = 0;
    rc.top      = 0;
    rc.right    = cxText;
    rc.bottom   = rcWork.bottom - rcWork.top;
    cyText      = DrawTextExW(hdc, (LPWSTR)lpmb->lpszText, -1, &rc, DT_CALCRECT | DT_WORDBREAK
        | DT_EXPANDTABS | DT_NOPREFIX | DT_EXTERNALLEADING | DT_EDITCONTROL, NULL);

    // Find the window size.
    cxBox += 2*SYSMET(CXFIXEDFRAME);
    cyBox = 2*SYSMET(CYFIXEDFRAME) + SYSMET(CYCAPTION) + YPixFromYDU(2*DU_OUTERMARGIN +
        DU_INNERMARGIN + DU_BTNHEIGHT, gpsi->cyMsgFontChar);

    cyBox += max(cyIcon, cyText);

    //
    // If the message box doesn't fit on the working area, we'll try wider
    // sizes successively:  6/8 of work then 7/8 of screen.
    //
    if (cyBox > rcWork.bottom - rcWork.top)
    {
        int cxTemp;

        cxTemp = MultDiv(rcWork.right - rcWork.left, 6, 8);

        if (cxMBMax == MultDiv(rcWork.right - rcWork.left, 5, 8))
        {
            cxMBMax = cxTemp;
            goto ReSize;
        }
        else if (cxMBMax == cxTemp)
        {
            CopyRect(&rcWork, &rcScreen);
            cxMBMax = MultDiv(rcWork.right - rcWork.left, 7, 8);
            goto ReSize;
        }
    }

    if (hFontOld)
        SelectFont(hdc, hFontOld);
    NtUserReleaseDC(NULL, hdc);

    // Find the window position
    xMB = (rcWork.left + rcWork.right - cxBox) / 2 + (gpsi->cntMBox * SYSMET(CXSIZE));
    xMB = max(xMB, 0);
    yMB = (rcWork.top + rcWork.bottom - cyBox) / 2 + (gpsi->cntMBox * SYSMET(CYSIZE));
    yMB = max(yMB, 0);

    // Bottom, right justify if we're going off the screen--but leave a
    // little gap

    if (xMB + cxBox > rcWork.right)
        xMB = rcWork.right - SYSMET(CXEDGE) - cxBox;

    //
    // Pin to the working area.  If it won't fit, then pin to the screen
    // height.  Bottom justify it at least if too big even for that, so
    // that the buttons are visible.
    //
    if (yMB + cyBox > rcWork.bottom)
    {
        yMB = rcWork.bottom - SYSMET(CYEDGE) - cyBox;
        if (yMB < rcWork.top)
            yMB = rcScreen.bottom - SYSMET(CYEDGE) - cyBox;
    }

    wTextLen = wcslen(lpmb->lpszText);

    // Find out the memory required for the Dlg template and try to alloc it
    hTemplate = LocalAlloc(LMEM_ZEROINIT, MB_FindDlgTemplateSize(lpmb));

    if (!hTemplate)
        goto SMB_Exit;

    lpDlgTmp = (LPBYTE) hTemplate;

    //
    // Setup the dialog style for the message box
    //
    dwStyleDlg = WS_POPUPWINDOW | WS_CAPTION | DS_ABSALIGN | DS_NOIDLEMSG |
                 DS_SETFONT | DS_3DLOOK;

    if ((dwStyleMsg & MB_MODEMASK) == MB_SYSTEMMODAL)
        dwStyleDlg |= DS_SYSMODAL | DS_SETFOREGROUND;
    else
        dwStyleDlg |= DS_MODALFRAME | WS_SYSMENU;

    if (dwStyleMsg & MB_SETFOREGROUND)
        dwStyleDlg |= DS_SETFOREGROUND;

    // Add the Header of the Dlg Template
    // BOGUS !!!  don't ADD bools
    lpDlgTmp = MB_UpdateDlgHdr((LPDLGTEMPLATE) lpDlgTmp, dwStyleDlg,
        (BYTE) (lpmb->cButtons + (wIconOrdNum != 0) + (lpmb->lpszText != NULL)),
        xMB, yMB, cxBox, cyBox, (LPWSTR)lpmb->lpszCaption, wCaptionLen);

    //
    // Center the buttons
    //

    cxFoo = (cxBox - 2*SYSMET(CXFIXEDFRAME) - cxButtons) / 2;

    lpDlgTmp = MB_AddPushButtons((LPDLGITEMTEMPLATE)lpDlgTmp, lpmb, cxFoo,
        cyBox - SYSMET(CYCAPTION) - (2 * SYSMET(CYFIXEDFRAME)) -
        YPixFromYDU(DU_OUTERMARGIN, gpsi->cyMsgFontChar));

    // Add Icon, if any, to the Dlg template
    //
    // The icon is always top justified.  If the text is shorter than the
    // height of the icon, we center it.  Otherwise the text will start at
    // the top.
    //
    if (wIconOrdNum) {
        OrdNum[0] = 0xFFFF;  // To indicate that an Ordinal number follows
        OrdNum[1] = (WORD) wIconOrdNum;

        lpDlgTmp = MB_UpdateDlgItem((LPDLGITEMTEMPLATE)lpDlgTmp, IDUSERICON,        /* Control Id        */
            SS_ICON | WS_GROUP | WS_CHILD | WS_VISIBLE,
            XPixFromXDU(DU_OUTERMARGIN, gpsi->cxMsgFontChar),  // X co-ordinate
            YPixFromYDU(DU_OUTERMARGIN, gpsi->cyMsgFontChar),   // Y co-ordinate
            0,  0,          // For Icons, CX and CY are ignored, can be zero
            OrdNum,         // Ordinal number of Icon
            sizeof(OrdNum)/sizeof(WCHAR), // Length of OrdNum
            STATICCODE);
    }

    /* Add the Text of the Message to the Dlg Template */
    if (lpmb->lpszText) {
        //
        // Center the text if shorter than the icon.
        //
        if (cyText >= cyIcon)
            cxFoo = 0;
        else
            cxFoo = (cyIcon - cyText) / 2;

        dwStyleText = SS_NOPREFIX | WS_GROUP | WS_CHILD | WS_VISIBLE | SS_EDITCONTROL;
        if (dwStyleMsg & MB_RIGHT) {
            dwStyleText |= SS_RIGHT;
            xText = cxBox - (SYSMET(CXSIZE) + cxText);
        } else {
            dwStyleText |= SS_LEFT;
            xText = cxIcon + XPixFromXDU(DU_OUTERMARGIN, gpsi->cxMsgFontChar);
        }

        MB_UpdateDlgItem((LPDLGITEMTEMPLATE)lpDlgTmp, -1, dwStyleText, xText,
            YPixFromYDU(DU_OUTERMARGIN, gpsi->cyMsgFontChar) + cxFoo,
            cxText, cyText,
            (LPWSTR)lpmb->lpszText, wTextLen, STATICCODE);
    }

    // The dialog template is ready
    NtUserCallNoParam(SFI_INCRMBOX);

    try {
        //
        // Set the normal cursor
        //
        hcurOld = NtUserSetCursor(LoadCursor(NULL, IDC_ARROW));

        lpmb->lpszIcon = (LPWSTR) hIcon;  // BUGBUG - How to diff this from a resource?

        if (!(lpmb->dwStyle & MB_USERICON))
        {
            UNICODE_STRING strSound;

            int wBeep = (LOWORD(lpmb->dwStyle & MB_ICONMASK)) >> MB_MASKSHIFT;
            if (!(wBeep >= (sizeof(iconsnd) / sizeof(WCHAR *)))) {
                RtlInitUnicodeString(&strSound, iconsnd[wBeep]);
                NtUserPlayEventSound(&strSound);
            }
        }

        iRetVal = (int)InternalDialogBox(hmodUser, hTemplate, 0L, hwndOwner,
            MB_DlgProcW, (LPARAM) lpmb, FALSE);

        //
        // Fix up return value
        if (iRetVal == -1)
            iRetVal = 0;                /* Messagebox should also return error */

         //
         // If the messagebox contains only OK button, then its ID is changed as
         // IDCANCEL in MB_DlgProc; So, we must change it back to IDOK irrespective
         // of whether ESC is pressed or Carriage return is pressed;
         //
        if (((dwStyleMsg & MB_TYPEMASK) == MB_OK) && iRetVal)
            iRetVal = IDOK;

    } finally {
        NtUserCallNoParam(SFI_DECRMBOX);
    }

    //
    // Restore the previous cursor
    //
    if (hcurOld)
        NtUserSetCursor(hcurOld);

SMB_Exit:
    if (hTemplate)
        UserLocalFree(hTemplate);

    if (hCaption) {
        UserLocalFree(hCaption);
    }

    if (hText) {
        UserLocalFree(hText);
    }

    return(iRetVal);
}

评分

参与人数 1好评 +1 精币 +3 收起 理由
7ian + 1 + 3 感谢分享,很给力!~

查看全部评分

回复 支持 1 反对 0

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表