示例#1
0
文件: trace.c 项目: mingpen/OpenNT
int far pascal zDialogBoxIndirect( HANDLE pp1, HANDLE pp2, HWND pp3, FARPROC pp4 )
{
    int r;
    FARPROC fp ;

    SaveRegs();

    fp = pp4 ;

    if (fp) {
        pp4 = (FARPROC)HookAdd( (void far *)DlgMesgProc,
            (void far *)fp );
    }

    /*
    ** Log IN Parameters (No Create/Destroy Checking Yet!)
    */
    LogIn( (LPSTR)"APICALL:DialogBoxIndirect HANDLE+HANDLE+HWND+FARPROC+",
        pp1, pp2, pp3, pp4 );

    /*
    ** Call the API!
    */
    RestoreRegs();
    GrovelDS();
    r = DialogBoxIndirect(pp1,pp2,pp3,pp4);
    UnGrovelDS();
    SaveRegs();
    /*
    ** Log Return Code & OUT Parameters (No Create/Destroy Checking Yet!)
    */
    LogOut( (LPSTR)"APIRET:DialogBoxIndirect int+++++",
        r, (short)0, (short)0, (short)0, (short)0 );

    RestoreRegs();
    return( r );
}
示例#2
0
void deviceconfig_open(HWND hwnd, device_t *device)
{
        device_config_t *config = device->config;
        uint16_t *data_block = malloc(16384);
        uint16_t *data;
        DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block;
        DLGITEMTEMPLATE *item;
        int y = 10;
        int id = IDC_CONFIG_BASE;

        memset(data_block, 0, 4096);
        
        dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU;
        dlg->x  = 10;
        dlg->y  = 10;
        dlg->cx = 220;
        dlg->cy = 70;
        
        data = (uint16_t *)(dlg + 1);
        
        *data++ = 0; /*no menu*/
        *data++ = 0; /*predefined dialog box class*/
        data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50);

        *data++ = 8; /*Point*/
        data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50);
        
#ifndef __MINGW64__
        if (((unsigned long)data) & 2)
#else
        if (((unsigned long long)data) & 2)
#endif
                data++;

        while (config->type != -1)
        {
                switch (config->type)
                {
                        case CONFIG_BINARY:
                        item = (DLGITEMTEMPLATE *)data;
                        item->x = 10;
                        item->y = y;
                        item->id = id++;
                
                        item->cx = 80;
                        item->cy = 15;

                        item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX;

                        data = (uint16_t *)(item + 1);
                        *data++ = 0xFFFF;
                        *data++ = 0x0080;    // button class

                        data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
                        *data++ = 0;              // no creation data
                        
                        y += 20;
                        break;

                        case CONFIG_SELECTION:
			case CONFIG_MIDI:
                        /*Combo box*/
                        item = (DLGITEMTEMPLATE *)data;
                        item->x = 70;
                        item->y = y;
                        item->id = id++;
                
                        item->cx = 140;
                        item->cy = 150;

                        item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;

                        data = (uint16_t *)(item + 1);
                        *data++ = 0xFFFF;
                        *data++ = 0x0085;    // combo box class

                        data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
                        *data++ = 0;              // no creation data
                        
#ifndef __MINGW64__
                        if (((unsigned long)data) & 2)
#else
                        if (((unsigned long long)data) & 2)
#endif
                                data++;

                        /*Static text*/
                        item = (DLGITEMTEMPLATE *)data;
                        item->x = 10;
                        item->y = y;
                        item->id = id++;
                
                        item->cx = 60;
                        item->cy = 15;

                        item->style = WS_CHILD | WS_VISIBLE;

                        data = (uint16_t *)(item + 1);
                        *data++ = 0xFFFF;
                        *data++ = 0x0082;    // static class

                        data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
                        *data++ = 0;              // no creation data
                        
#ifndef __MINGW64__
                        if (((unsigned long)data) & 2)
#else
                        if (((unsigned long long)data) & 2)
#endif
                                data++;

                        y += 20;
                        break;
                }

#ifndef __MINGW64__
                if (((unsigned long)data) & 2)
#else
                if (((unsigned long long)data) & 2)
#endif
                        data++;

                config++;
        }

        dlg->cdit = (id - IDC_CONFIG_BASE) + 2;

//    DEFPUSHBUTTON   "OK",IDOK,64,232,50,14, WS_TABSTOP
//    PUSHBUTTON      "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP

        item = (DLGITEMTEMPLATE *)data;
        item->x = 20;
        item->y = y;
        item->cx = 50;
        item->cy = 14;
        item->id = IDOK;  // OK button identifier
        item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

        data = (uint16_t *)(item + 1);
        *data++ = 0xFFFF;
        *data++ = 0x0080;    // button class

        data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50);
        *data++ = 0;              // no creation data

#ifndef __MINGW64__
        if (((unsigned long)data) & 2)
#else
        if (((unsigned long long)data) & 2)
#endif
		data++;
                
        item = (DLGITEMTEMPLATE *)data;
        item->x = 80;
        item->y = y;
        item->cx = 50;
        item->cy = 14;
        item->id = IDCANCEL;  // OK button identifier
        item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

        data = (uint16_t *)(item + 1);
        *data++ = 0xFFFF;
        *data++ = 0x0080;    // button class

        data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50);
        *data++ = 0;              // no creation data

        dlg->cy = y + 20;
        
        config_device = device;
        
        DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc);

        free(data_block);
}
示例#3
0
int  DebugWinlogonInterface::WlxDialogBoxIndirect(HANDLE hInst, LPCDLGTEMPLATE hDialogTemplate, HWND hwndOwner, DLGPROC dlgprc)
{
    return (int) DialogBoxIndirect((HINSTANCE) hInst, hDialogTemplate, hwndOwner, dlgprc);
}
示例#4
0
int
WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
    WIN_DialogData *dialog;
    int i, x, y;
    UINT_PTR which;
    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
    HFONT DialogFont;
    SIZE Size;
    RECT TextSize;
    wchar_t* wmessage;
    TEXTMETRIC TM;


    const int ButtonWidth = 88;
    const int ButtonHeight = 26;
    const int TextMargin = 16;
    const int ButtonMargin = 12;


    /* Jan 25th, 2013 - [email protected]
     *
     *
     * I've tried to make this more reasonable, but I've run in to a lot
     * of nonsense.
     *
     * The original issue is the code was written in pixels and not
     * dialog units (DLUs). All DialogBox functions use DLUs, which
     * vary based on the selected font (yay).
     *
     * According to MSDN, the most reliable way to convert is via
     * MapDialogUnits, which requires an HWND, which we don't have
     * at time of template creation.
     *
     * We do however have:
     *  The system font (DLU width 8 for me)
     *  The font we select for the dialog (DLU width 6 for me)
     *
     * Based on experimentation, *neither* of these return the value
     * actually used. Stepping in to MapDialogUnits(), the conversion
     * is fairly clear, and uses 7 for me.
     *
     * As a result, some of this is hacky to ensure the sizing is
     * somewhat correct.
     *
     * Honestly, a long term solution is to use CreateWindow, not CreateDialog.
     *

     *
     * In order to get text dimensions we need to have a DC with the desired font.
     * I'm assuming a dialog box in SDL is rare enough we can to the create.
     */
    HDC FontDC = CreateCompatibleDC(0);

    {
        /* Create a duplicate of the font used in system message boxes. */
        LOGFONT lf;
        NONCLIENTMETRICS NCM;
        NCM.cbSize = sizeof(NCM);
        SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &NCM, 0);
        lf = NCM.lfMessageFont;
        DialogFont = CreateFontIndirect(&lf);
    }

    /* Select the font in to our DC */
    SelectObject(FontDC, DialogFont);

    {
        /* Get the metrics to try and figure our DLU conversion. */
        GetTextMetrics(FontDC, &TM);
        s_BaseUnitsX = TM.tmAveCharWidth + 1;
        s_BaseUnitsY = TM.tmHeight;
    }

    /* Measure the *pixel* size of the string. */
    wmessage = WIN_UTF8ToString(messageboxdata->message);
    SDL_zero(TextSize);
    Size.cx = DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT);

    /* Add some padding for hangs, etc. */
    TextSize.right += 2;
    TextSize.bottom += 2;

    /* Done with the DC, and the string */
    DeleteDC(FontDC);
    SDL_free(wmessage);

    /* Increase the size of the dialog by some border spacing around the text. */
    Size.cx = TextSize.right - TextSize.left;
    Size.cy = TextSize.bottom - TextSize.top;
    Size.cx += TextMargin * 2;
    Size.cy += TextMargin * 2;

    /* Ensure the size is wide enough for all of the buttons. */
    if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin)
        Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin;

    /* Add vertical space for the buttons and border. */
    Size.cy += ButtonHeight + TextMargin;

    dialog = CreateDialogData(Size.cx, Size.cy, messageboxdata->title);
    if (!dialog) {
        return -1;
    }

    if (!AddDialogStatic(dialog, TextMargin, TextMargin, TextSize.right - TextSize.left, TextSize.bottom - TextSize.top, messageboxdata->message)) {
        FreeDialogData(dialog);
        return -1;
    }

    /* Align the buttons to the right/bottom. */
    x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
    y = Size.cy - ButtonHeight - ButtonMargin;
    for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
        SDL_bool isDefault;

        if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
            isDefault = SDL_TRUE;
        } else {
            isDefault = SDL_FALSE;
        }
        if (!AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttons[i].text, i, isDefault)) {
            FreeDialogData(dialog);
            return -1;
        }
        x += ButtonWidth + ButtonMargin;
    }

    /* FIXME: If we have a parent window, get the Instance and HWND for them */
    which = DialogBoxIndirect(NULL, (DLGTEMPLATE*)dialog->lpDialog, NULL, (DLGPROC)MessageBoxDialogProc);
    *buttonid = buttons[which].buttonid;

    FreeDialogData(dialog);
    return 0;
}
示例#5
0
/*
 * The purpose of this function is to layout and display the pub/sub options
 * dialog based on a variable number of input options.  The input option
 * mask dictates which options are enabled by default, while the output mask is
 * used to indicate which options were selected by the user (from the 
 * available options specified by in. Mask determines which options are available.  
 */
void showOptionsDlg(HWND parent, char **optionLabels, int numOptions, Options *in, Options *out, Options *mask) {
   HDC dc = GetDC(parent);
   
   //need to create font used by dialog and select into context
   //so that we can compute text string sizes
   HFONT font = CreateFont(8, 0, 0, 0, FW_NORMAL, false, false, false, 
                    ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 
                    DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
                    "MS Shell Dlg");
   SelectObject(dc, (HGDIOBJ) font);
   
   SIZE sz;
   
   optsIn = in;
   optsOut = out;
   optsMask = mask;
   numOpts = numOptions;

   char desc[1024];
   int plistExists = 0;
  
   //This is the number of individual items that will be created within the dialog
   //7 represents 3 static stings + 4 push buttons
   //* 3 represents the 3 items per option (option name + 2 checkboxes)
   int numItems = 7 + numOptions * 3;
   int textHeight = 0;
   int textWidth = 0;
   //Row start y coordinate begins after accounting for the border height
   int rowStart = BORDER;
   
   //loop to find the widest/tallest option label
   for (int i = 0; i < numOptions; i++) {
      GetTextExtentPoint32(dc, optionLabels[i], strlen(optionLabels[i]), &sz);
      if (sz.cy > textHeight) {
         textHeight = sz.cy;
      }
      if (sz.cx > textWidth) {
         textWidth = sz.cx;
      }
   }

   //comput the vertical height of the push buttons
   int buttonHeight = textHeight * 2;

   //compute the width of the buttons based on the width of the longest button label
   //the size in the following allows for 2 spaces on either side of the label
   GetTextExtentPoint32(dc, "Subscribe Only", 18, &sz);
   int buttonWidth = sz.cx;
   
   //compute the width and height of the dialog box based on the 
   //sums of the component dimensions and spacing
   short height = 2 * BORDER + (numOptions + 1) * textHeight + (numOptions) * TEXT_SPACING + 
                  TEXT_TO_BUTTON_SPACING + BUTTON_SPACING + buttonHeight * 2;
   short width = 2 * BORDER + textWidth + 2 * CB_SIZE + 2 * CB_SPACE;
   
   //compute width required to accomodate the buttons
   short buttonReqWidth = BORDER * 2 + 2 * buttonWidth + BUTTON_SPACING;
   
   //recompute width if buttons are wider than option labels
   if (width < buttonReqWidth) {
      width = buttonReqWidth;
   }
   
   //compute x offset to the pub checkboxes
   int cbStart = width - BORDER - 2 * CB_SIZE - 2 * CB_SPACE;
   
   //build the dialog template into a Buffer
   Buffer dlgTemplate;
   DLGTEMPLATE temp, *pTemp;
   temp.style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_CENTER | DS_MODALFRAME | WS_CAPTION | DS_SETFONT;
   temp.dwExtendedStyle = 0;
   temp.cdit = numItems;
   temp.x = 0;
   temp.y = 0;
   temp.cx = width;
   temp.cy = height;
   dlgTemplate.write(&temp, sizeof(temp));
   dlgTemplate.writeShort(0);   //no menu
   dlgTemplate.writeShort(0);   //predefined dialog class

   desc[0] = '\0';
   plistExists = GetDlgItemText(parent, IDC_PROJECT_LIST, desc, sizeof(desc));
   //if(GetDlgItemText(parent, IDC_PROJECT_LIST, desc, sizeof(desc)) ) { //GetDlgItem returns #TChar or NULL
   if (strcmp(desc, "<New project>") == 0 || !plistExists) {   //should be for snapshots too...
      dlgTemplate.writeWide("Set Permissions");        //unicode dialog title
   }
   else {
      dlgTemplate.writeWide("Project Join Options");   //unicode dialog title
   }
   #if DEBUG
      msg(PLUGIN_NAME": PROJECT LIST is %s , strcmp is: %d \n", desc,strcmp(desc,"<New project>"));
   #endif

   dlgTemplate.writeShort(0x0800);   //font size in network byte order
   dlgTemplate.writeWide("MS Shell Dlg");   //unicode font name
   padBuffer(dlgTemplate);
   
   DLGITEMTEMPLATE item, text;
   
   //common values for all static text elements
   //Start with the three static column headers
   text.style = WS_CHILD | WS_VISIBLE | SS_LEFT;
   text.dwExtendedStyle = 0;
   text.x = BORDER;
   text.y = rowStart;
   text.cx = textWidth;
   text.cy = textHeight;
   text.id = 0xFFFF;

   dlgTemplate.write(&text, sizeof(text));
   dlgTemplate.write(STATIC_CLASS, sizeof(STATIC_CLASS)); //item class
   dlgTemplate.writeWide("Options"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

   //center the Pub label over the pub checkbox location
   GetTextExtentPoint32(dc, "Pub", 3, &sz);
   text.x = cbStart + (CB_SIZE - sz.cx) / 2;
   text.cx = sz.cx;

   dlgTemplate.write(&text, sizeof(text));
   dlgTemplate.write(STATIC_CLASS, sizeof(STATIC_CLASS)); //item class
   dlgTemplate.writeWide("Pub"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

   //center the Sub label over the sub checkbox location
   GetTextExtentPoint32(dc, "Sub", 3, &sz);
   text.x = cbStart + CB_SIZE + CB_SPACE + (CB_SIZE - sz.cx) / 2;
   text.cx = sz.cx;

   dlgTemplate.write(&text, sizeof(text));
   dlgTemplate.write(STATIC_CLASS, sizeof(STATIC_CLASS)); //item class
   dlgTemplate.writeWide("Sub"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

   rowStart += textHeight;
   
   item.style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | WS_TABSTOP;  
   item.dwExtendedStyle = 0;
   item.cx = CB_SIZE;
   item.cy = CB_SIZE;

   //print all of the option labels and their checkboxes
   int bit = 1;
   for (int i = 0; i < numOptions; i++) {
      rowStart += TEXT_SPACING;
      
      text.x = BORDER;
      text.y = rowStart;
      text.cx = textWidth;
   
      dlgTemplate.write(&text, sizeof(text));
      dlgTemplate.write(STATIC_CLASS, sizeof(STATIC_CLASS)); //item class
      dlgTemplate.writeWide(optionLabels[i]); //item text  unicode
      dlgTemplate.writeShort(0);   //class data
      padBuffer(dlgTemplate);

      //test option bits to see if the publish bit is set
      if (optsMask->pub & bit) {
         item.style &= ~WS_DISABLED;
      }
      else {
         item.style |= WS_DISABLED;
      }
      item.x = cbStart;
      item.y = rowStart;
      item.id = COLLAB_CB_BASE + i * 2;
      
      dlgTemplate.write(&item, sizeof(item));
      dlgTemplate.write(BUTTON_CLASS, sizeof(BUTTON_CLASS)); //item class
      dlgTemplate.writeWide(""); //item text  unicode
      dlgTemplate.writeShort(0);   //class data
      padBuffer(dlgTemplate);

      //test option bits to see if the subscribe bit is set
      if (optsMask->sub & bit) {
         item.style &= ~WS_DISABLED;
      }
      else {
         item.style |= WS_DISABLED;
      }
      item.x = cbStart + CB_SIZE + CB_SPACE;
      item.id = COLLAB_CB_BASE + i * 2 + 1;
      
      dlgTemplate.write(&item, sizeof(item));
      dlgTemplate.write(BUTTON_CLASS, sizeof(BUTTON_CLASS)); //item class
      dlgTemplate.writeWide(""); //item text  unicode
      dlgTemplate.writeShort(0);   //class data
      padBuffer(dlgTemplate);

      rowStart += textHeight;
      bit <<= 1;
   }

   rowStart += TEXT_TO_BUTTON_SPACING;

   //layout the 4 pushbuttons
   item.style = WS_CHILD | WS_VISIBLE | BS_CENTER | BS_PUSHBUTTON | WS_TABSTOP;  
   item.x = (width - 2 * buttonWidth - BUTTON_SPACING) / 2;
   item.y = rowStart;
   item.cx = buttonWidth;
   item.cy = buttonHeight;
   item.id = COLLAB_SUB_ALL;
   
   dlgTemplate.write(&item, sizeof(item));
   dlgTemplate.write(BUTTON_CLASS, sizeof(BUTTON_CLASS)); //item class
   dlgTemplate.writeWide("Subscribe All"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

   item.x += buttonWidth + BUTTON_SPACING;
   item.id = COLLAB_SUB_ONLY;
   
   dlgTemplate.write(&item, sizeof(item));
   dlgTemplate.write(BUTTON_CLASS, sizeof(BUTTON_CLASS)); //item class
   dlgTemplate.writeWide("Subscribe Only"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

   rowStart += buttonHeight + BUTTON_SPACING;

   //must align each item to dword 
   item.style = WS_CHILD | WS_VISIBLE | BS_CENTER | BS_DEFPUSHBUTTON | WS_TABSTOP;  
   item.x = (width - 2 * buttonWidth - BUTTON_SPACING) / 2;
   item.y = rowStart;
   item.id = IDOK;
   
   dlgTemplate.write(&item, sizeof(item));
   dlgTemplate.write(BUTTON_CLASS, sizeof(BUTTON_CLASS)); //item class
   dlgTemplate.writeWide("OK"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

   //must align each item to dword 
   item.style = WS_CHILD | WS_VISIBLE | BS_CENTER | BS_PUSHBUTTON | WS_TABSTOP;  

   item.x += buttonWidth + BUTTON_SPACING;
   item.id = IDCANCEL;
   
   dlgTemplate.write(&item, sizeof(item));
   dlgTemplate.write(BUTTON_CLASS, sizeof(BUTTON_CLASS)); //item class
   dlgTemplate.writeWide("Cancel"); //item text  unicode
   dlgTemplate.writeShort(0);   //class data
   padBuffer(dlgTemplate);

//   hexDump(dlgTemplate.get_buf(), dlgTemplate.size());
   
   //need to point this to "global memory" ??
   HGLOBAL hgbl = GlobalAlloc(GMEM_ZEROINIT, dlgTemplate.size());
   DLGTEMPLATE *lpdt = (DLGTEMPLATE*)GlobalLock(hgbl);
   memcpy(lpdt, dlgTemplate.get_buf(), dlgTemplate.size());

   GlobalUnlock(hgbl); 
   int res = DialogBoxIndirect(hModule, (LPDLGTEMPLATE)hgbl, parent, OptionsDlgProc); 
   if (res == 1) {
      //read checkboxes for options
   }
   else if (res == -1) {
      DWORD err = GetLastError();
      msg(PLUGIN_NAME": Options dialog error %d, 0x%x\n", err, err);
   }
   GlobalFree(hgbl);
   ReleaseDC(parent, dc); 
}
示例#6
0
	BOOL Win32PopupDialog::ShowMessageBox(HWND hwnd)
	{
		BOOL fSuccess = FALSE;
		HDC hdc = GetDC(hwnd);

		if (hdc)
		{
			NONCLIENTMETRICSW ncm = { sizeof(ncm) };
			if (SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0)) {
				DialogTemplate tmp;
				std::wstring ws;

				int controlCount = 2;	// at minimum, static label and OK button
				if(this->showCancelButton) controlCount++;
				if(this->showInputText) controlCount++;

				int labelHeight = 14;
				int width = 300;
				int height = 90;
				int margin = 10;
				int buttonWidth = 50;
				int buttonHeight = 14;
				int inputHeight = 14;

				if(! this->showInputText)
				{
					height -= (inputHeight + margin);
				}

				// Write out the extended dialog template header
				tmp.Write<WORD>(1); // dialog version
				tmp.Write<WORD>(0xFFFF); // extended dialog template
				tmp.Write<DWORD>(0); // help ID
				tmp.Write<DWORD>(0); // extended style
				tmp.Write<DWORD>(WS_CAPTION | DS_FIXEDSYS | DS_SETFONT | DS_MODALFRAME);	// DS_FIXEDSYS removes the close decoration
				tmp.Write<WORD>(controlCount); // number of controls
				tmp.Write<WORD>(32); // X
				tmp.Write<WORD>(32); // Y
				tmp.Write<WORD>(width); // width
				tmp.Write<WORD>(height); // height
				tmp.WriteString(L""); // no menu
				tmp.WriteString(L""); // default dialog class
				//tmp.WriteString(pszTitle); // title
				tmp.WriteString(ws.assign(title.begin(), title.end()).c_str()); // title

				// Next comes the font description.
				// See text for discussion of fancy formula.
				if (ncm.lfMessageFont.lfHeight < 0)
				{
					ncm.lfMessageFont.lfHeight = -MulDiv(ncm.lfMessageFont.lfHeight, 72, GetDeviceCaps(hdc, LOGPIXELSY));
				}
				tmp.Write<WORD>((WORD)ncm.lfMessageFont.lfHeight); // point
				tmp.Write<WORD>((WORD)ncm.lfMessageFont.lfWeight); // weight
				tmp.Write<BYTE>(ncm.lfMessageFont.lfItalic); // Italic
				tmp.Write<BYTE>(ncm.lfMessageFont.lfCharSet); // CharSet
				tmp.WriteString(ncm.lfMessageFont.lfFaceName);

				// First control - static label
				tmp.AlignToDword();
				tmp.Write<DWORD>(0); // help id
				tmp.Write<DWORD>(0); // window extended style
				tmp.Write<DWORD>(WS_CHILD | WS_VISIBLE); // style
				tmp.Write<WORD>(margin); // x
				tmp.Write<WORD>(margin); // y
				tmp.Write<WORD>(width - (2 * margin)); // width
				tmp.Write<WORD>(labelHeight); // height
				tmp.Write<DWORD>(-1); // control ID
				tmp.Write<DWORD>(0x0082FFFF); // static
				tmp.WriteString(ws.assign(message.begin(), message.end()).c_str()); // text
				tmp.Write<WORD>(0); // no extra data

				// Second control - the OK button.
				tmp.AlignToDword();
				tmp.Write<DWORD>(0); // help id
				tmp.Write<DWORD>(0); // window extended style
				tmp.Write<DWORD>(WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON); // style
				tmp.Write<WORD>(width - margin - buttonWidth); // x
				tmp.Write<WORD>(height - margin - buttonHeight); // y
				tmp.Write<WORD>(buttonWidth); // width
				tmp.Write<WORD>(buttonHeight); // height
				tmp.Write<DWORD>(IDOK); // control ID
				tmp.Write<DWORD>(0x0080FFFF); // button class atom
				tmp.WriteString(L"OK"); // text
				tmp.Write<WORD>(0); // no extra data

				if(this->showCancelButton)
				{
					// The Cancel button
					tmp.AlignToDword();
					tmp.Write<DWORD>(0); // help id
					tmp.Write<DWORD>(0); // window extended style
					tmp.Write<DWORD>(WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON); // style
					tmp.Write<WORD>(width - 2 * margin - 2 * buttonWidth); // x
					tmp.Write<WORD>(height - margin - buttonHeight); // y
					tmp.Write<WORD>(buttonWidth); // width
					tmp.Write<WORD>(buttonHeight); // height
					tmp.Write<DWORD>(IDCANCEL); // control ID
					tmp.Write<DWORD>(0x0080FFFF); // button class atom
					tmp.WriteString(L"Cancel"); // text
					tmp.Write<WORD>(0); // no extra data
				}

				if(this->showInputText)
				{
					// The input field
					tmp.AlignToDword();
					tmp.Write<DWORD>(0); // help id
					tmp.Write<DWORD>(0); // window extended style
					tmp.Write<DWORD>(ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE); // style
					tmp.Write<WORD>(margin); // x
					tmp.Write<WORD>(margin + labelHeight + margin); // y
					tmp.Write<WORD>(width - (2 * margin)); // width
					tmp.Write<WORD>(inputHeight); // height
					tmp.Write<DWORD>(ID_INPUT_FIELD); // control ID
					tmp.Write<DWORD>(0x0081FFFF); // edit class atom
					tmp.WriteString(ws.assign(inputText.begin(), inputText.end()).c_str()); // text
					tmp.Write<WORD>(0); // no extra data
				}

				// Template is ready - go display it.
				fSuccess = DialogBoxIndirect(GetModuleHandle(NULL), tmp.Template(), hwnd, &Win32PopupDialog::Callback) >= 0;
			}
			ReleaseDC(NULL, hdc); // fixed 11 May
		}

		return fSuccess;
	}
示例#7
0
//-----------------------------------------------------------------------------------------------------------------------------------------
//  Create the Dialog Box to get input from the user
//-----------------------------------------------------------------------------------------------------------------------------------------
LRESULT DisplayMiniDumpDialog(HINSTANCE hinst, HWND hwndOwner)
{
   HGLOBAL hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
   if (!hgbl) return -1;

   //-----------------------------------------------------------------
   // Define the dialog box
   //-----------------------------------------------------------------
   LPDLGTEMPLATE lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
   lpdt->style = WS_POPUP | WS_BORDER | DS_MODALFRAME | WS_CAPTION;
   lpdt->cdit = 3;         // Number of controls
   lpdt->x  = 100;  
   lpdt->y  = 100;
   lpdt->cx = 300; 
   lpdt->cy = 90;

   LPWORD lpw = (LPWORD)(lpdt + 1);
   *lpw++ = 0;             // No menu
   *lpw++ = 0;             // Predefined dialog box class (by default)

   LPWSTR lpwsz = (LPWSTR)lpw;
   S32 nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "MiniDump Crash Report", -1, lpwsz, 50);
   lpw += nchar;

   //-----------------------------------------------------------------
   // Define a static text message
   //-----------------------------------------------------------------
   lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
   LPDLGITEMTEMPLATE lpdit = (LPDLGITEMTEMPLATE)lpw;
   lpdit->x  = 10; 
   lpdit->y  = 10;
   lpdit->cx = 290; 
   lpdit->cy = 10;
   lpdit->id = ID_TEXT;    // Text identifier
   lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

   lpw = (LPWORD)(lpdit + 1);
   *lpw++ = 0xFFFF;
   *lpw++ = 0x0082;        // Static class

   LPSTR msg = "The program has crashed.  Please describe what was happening:";
   for (lpwsz = (LPWSTR)lpw; *lpwsz++ = (WCHAR)*msg++;);
   lpw = (LPWORD)lpwsz;

   *lpw++ = 0;             // No creation data        

   //-----------------------------------------------------------------
   // Define a DONE button
   //-----------------------------------------------------------------
   lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
   lpdit = (LPDLGITEMTEMPLATE)lpw;
   lpdit->x  = 265; 
   lpdit->y  = 75;
   lpdit->cx = 25; 
   lpdit->cy = 12;
   lpdit->id = ID_DONE;       // OK button identifier
   lpdit->style = WS_CHILD | WS_VISIBLE | WS_TABSTOP;// | BS_DEFPUSHBUTTON;

   lpw = (LPWORD)(lpdit + 1);
   *lpw++ = 0xFFFF;
   *lpw++ = 0x0080;        // Button class

   lpwsz = (LPWSTR)lpw;
   nchar = 1 + MultiByteToWideChar(CP_ACP, 0, "Done", -1, lpwsz, 50);
   lpw += nchar;
   *lpw++ = 0;					// No creation data

   //-----------------------------------------------------------------
   // Define a text entry message
   //-----------------------------------------------------------------
   lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
   lpdit = (LPDLGITEMTEMPLATE)lpw;
   lpdit->x  = 10; 
   lpdit->y  = 22;
   lpdit->cx = 280; 
   lpdit->cy = 50;
   lpdit->id = ID_USERTEXT;    // Text identifier
   lpdit->style = ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE;

   lpw = (LPWORD)(lpdit + 1);
   *lpw++ = 0xFFFF;
   *lpw++ = 0x0081;        // Text edit class

   *lpw++ = 0;             // No creation data



   GlobalUnlock(hgbl); 
   LRESULT ret = DialogBoxIndirect(	hinst, 
      (LPDLGTEMPLATE)hgbl, 
      hwndOwner, 
      (DLGPROC)MiniDumpDialogProc); 
   GlobalFree(hgbl); 
   return ret; 
}
	BOOL Win32PopupDialog::ShowMessageBox(HWND hwnd)
	{
		BOOL fSuccess = FALSE;
		HDC hdc = GetDC(hwnd);

		if (hdc)
		{
			NONCLIENTMETRICSW nonClientMetrics = { sizeof(NONCLIENTMETRICSW) };
			if (SystemParametersInfoW(
				SPI_GETNONCLIENTMETRICS, 0, &nonClientMetrics, 0))
			{
				DialogTemplate tmp;
				std::wstring wideTitle(::UTF8ToWide(title));
				std::wstring wideInputText;
				if (this->showInputText)
					wideInputText.assign(::UTF8ToWide(inputText));

				int controlCount = 2;	// at minimum, static label and OK button
				if (this->showCancelButton)
					controlCount++;
				if (this->showInputText)
					controlCount++;

				int messageLines = 0;
				int newlines = CountMatches(message, "\n");
				int tabs = CountMatches(message, "\t");
				int spaces = CountMatches(message, " ");

				if (newlines == 0 && tabs == 0 && spaces == 0)
				{
					std::string tempMessage(message);
					if (tempMessage.length() != 0)
					{
						int insertAt = 60;
						int count = 0;

						std::string::iterator it = tempMessage.begin();
						for (; it < tempMessage.end(); it++)
						{
							count++;
							if (count == 60)
							{	
								count = 0;
								message.insert(insertAt, "\n");
								insertAt += 60;
							}
						}
					}
				}
				
				std::wstring wideMessage(::UTF8ToWide(message));
				messageLines = message.length() / 60;
				messageLines += ((int) ceil((double)tabs / 14));
				messageLines += newlines;
				
				if (tabs == 0 || newlines == 0)
					messageLines++;

				int labelHeight = 14;
				int width = 200;
				int margin = 10;
				int buttonWidth = 50;
				int buttonHeight = 14;
				int inputHeight = 14;
				int messageHeight = (messageLines * 12) + (messageLines * margin);
				int height = messageHeight + 56;
				
				if (!this->showInputText)
				{
					height -= (inputHeight + margin);
				}

				// Write out the extended dialog template header
				tmp.Write<WORD>(1); // dialog version
				tmp.Write<WORD>(0xFFFF); // extended dialog template
				tmp.Write<DWORD>(0); // help ID
				tmp.Write<DWORD>(0); // extended style
				tmp.Write<DWORD>(WS_CAPTION | WS_BORDER | DS_ABSALIGN | DS_SETFONT);
				tmp.Write<WORD>(controlCount); // number of controls
				tmp.Write<WORD>(32); // X
				tmp.Write<WORD>(32); // Y
				tmp.Write<WORD>(width); // width
				tmp.Write<WORD>(height); // height
				tmp.WriteString(L""); // no menu
				tmp.WriteString(L""); // default dialog class
				//tmp.WriteString(pszTitle); // title
				tmp.WriteString(wideTitle.c_str()); // title

				// Next comes the font description.
				// See text for discussion of fancy formula.
				
				if (nonClientMetrics.lfMessageFont.lfHeight < 0)
				{
					int dpi = GetDeviceCaps(hdc, LOGPIXELSY);
					nonClientMetrics.lfMessageFont.lfHeight =
						-MulDiv(nonClientMetrics.lfMessageFont.lfHeight, 72, dpi);
				}
				tmp.Write<WORD>((WORD)nonClientMetrics.lfMessageFont.lfHeight); // point
				tmp.Write<WORD>((WORD)nonClientMetrics.lfMessageFont.lfWeight); // weight
				tmp.Write<BYTE>(nonClientMetrics.lfMessageFont.lfItalic); // Italic
				tmp.Write<BYTE>(nonClientMetrics.lfMessageFont.lfCharSet); // CharSet
				tmp.WriteString(nonClientMetrics.lfMessageFont.lfFaceName);

				// First control - static label
				tmp.AlignToDword();
				tmp.Write<DWORD>(0); // help id
				tmp.Write<DWORD>(0); // window extended style
				tmp.Write<DWORD>(WS_CHILD | WS_VISIBLE | SS_LEFT); // style
				tmp.Write<WORD>(margin); // x
				tmp.Write<WORD>(margin); // y
				tmp.Write<WORD>(width - (2 * margin)); // width
				//tmp.Write<WORD>(labelHeight); // height
				tmp.Write<WORD>(messageHeight); // height
				tmp.Write<DWORD>(-1); // control ID
				tmp.Write<DWORD>(0x0082FFFF); // static
				//tmp.Write<DWORD>(SS_LEFT);
				tmp.WriteString(wideMessage.c_str()); // text
				tmp.Write<WORD>(0); // no extra data

				// Second control - the OK button.
				tmp.AlignToDword();
				tmp.Write<DWORD>(0); // help id
				tmp.Write<DWORD>(0); // window extended style
				tmp.Write<DWORD>(WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON); // style
				tmp.Write<WORD>(width - margin - buttonWidth); // x
				tmp.Write<WORD>(height - margin - buttonHeight); // y
				tmp.Write<WORD>(buttonWidth); // width
				tmp.Write<WORD>(buttonHeight); // height
				tmp.Write<DWORD>(IDCANCEL); // control ID
				tmp.Write<DWORD>(0x0080FFFF); // button class atom
				tmp.WriteString(L"Cancel"); // text
				tmp.Write<WORD>(0); // no extra data

				if (this->showCancelButton)
				{
					// The Cancel button
					tmp.AlignToDword();
					tmp.Write<DWORD>(0); // help id
					tmp.Write<DWORD>(0); // window extended style
					tmp.Write<DWORD>(WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON); // style
					tmp.Write<WORD>(width - 2 * margin - 2 * buttonWidth); // x
					tmp.Write<WORD>(height - margin - buttonHeight); // y
					tmp.Write<WORD>(buttonWidth); // width
					tmp.Write<WORD>(buttonHeight); // height
					tmp.Write<DWORD>(IDOK); // control ID
					tmp.Write<DWORD>(0x0080FFFF); // button class atom
					tmp.WriteString(L"OK"); // text
					tmp.Write<WORD>(0); // no extra data
				}

				if (this->showInputText)
				{
					// The input field
					tmp.AlignToDword();
					tmp.Write<DWORD>(0); // help id
					tmp.Write<DWORD>(0); // window extended style
					tmp.Write<DWORD>(ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE); // style
					tmp.Write<WORD>(margin); // x
					tmp.Write<WORD>(margin + labelHeight + margin); // y
					tmp.Write<WORD>(width - (2 * margin)); // width
					tmp.Write<WORD>(inputHeight); // height
					tmp.Write<DWORD>(ID_INPUT_FIELD); // control ID
					tmp.Write<DWORD>(0x0081FFFF); // edit  class atom
					tmp.WriteString(wideInputText.c_str()); // text
					tmp.Write<WORD>(0); // no extra data
				}

				// Template is ready - go display it.
				fSuccess = DialogBoxIndirect(
					GetModuleHandle(NULL),
					tmp.Template(),
					hwnd,
					&Win32PopupDialog::Callback) >= 0;
			}
			ReleaseDC(NULL, hdc); // fixed 11 May
		}
		return fSuccess;
	}
示例#9
0
LRESULT DisplayMessage(wchar_t* title, int title_len, wchar_t* message, int message_len, wchar_t* button_label[], int button_len[], int num_buttons)
{
    DLGTEMPLATE* dlg_template;
    DLGITEMTEMPLATE* item_template;
    WORD* cursor;	// 16 bits words pointer
    LRESULT ret_code;
	void* buf;
	int i;
	int next_x;
	int button_width = 80;	// Width of a button
	int button_gap = 6;	// Width of the space separating two buttons
	int left_margin = 10;	// Left dialog margin
	int right_margin = 10;	// Right dialog margin
	int top_margin = 10;
	int bottom_margin = 10;
	int static_height = 40;	// Height of the space where static text is displayed
	int static_to_buttons_margin = num_buttons > 0 ? 5 : 0;
	int button_height = num_buttons > 0 ? 15 : 0;
	int num_gaps = num_buttons ? num_buttons -1 : 0;
	int static_width = num_buttons ? num_buttons * button_width + button_gap * num_gaps : 80;
	int buf_len;
	int font_len = wcslen(FONT_NAME);

	// Compute length of work buffer and allocate it
	buf_len = sizeof(DLGTEMPLATE) + 4 + title_len + 1 + font_len + 1 + message_len + 1 + sizeof(DLGITEMTEMPLATE) + 4 + 2 + num_buttons * sizeof(DLGITEMTEMPLATE) + 
				+ 100; // Allow for into account possible alignment padding as well as extra fields (class atoms, user data)

	for (i=0; i<num_buttons; i++)
		buf_len += button_len[i] + 1;	

	buf = malloc(buf_len);

    dlg_template = (DLGTEMPLATE*) buf;
 
    // Dialog header
 
    dlg_template->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | DS_SETFONT;
	dlg_template->dwExtendedStyle = 0;
    dlg_template->cdit = 1 + num_buttons;         // Number of controls
    dlg_template->x  = 0;			// In Dialog Box Units
	dlg_template->y  = 0;	
    dlg_template->cx = left_margin + static_width + right_margin;
	dlg_template->cy = top_margin + static_height + static_to_buttons_margin + button_height + bottom_margin;

    cursor = (WORD*)(dlg_template + 1);	// Point past DLGTEMPLATE structure
    *cursor++ = 0;            // Menu
    *cursor++ = 0;            // Default Dialog class

    // Copy title, add NUL and shift cursor
	wmemcpy(cursor, title, title_len);
	cursor += title_len;
	*cursor++ = 0;

	// Type point and font name (as DS_FONT was specified)
	*cursor++ = FONT_SIZE;
	wmemcpy(cursor, FONT_NAME, font_len);
	cursor += font_len;
	*cursor++ = 0;

	// Item templates need to be DWORD aligned
	ALIGN4(cursor);

	// Static control

    item_template = (DLGITEMTEMPLATE*) cursor;
    item_template->style = WS_CHILD | WS_VISIBLE | SS_CENTER;
	item_template->dwExtendedStyle = 0;
	item_template->x  = left_margin;
	item_template->y  = top_margin;
    item_template->cx = static_width;
	item_template->cy = static_height;
    item_template->id = -1;

    // Move past DLGITEMTEMPLATE structure
	cursor = (WORD*)(item_template + 1);
  
	// Static class
	*cursor++ = 0xFFFF;
    *cursor++ = 0x0082;

	// Title
	wmemcpy(cursor, message, message_len);
	cursor += message_len;
	*cursor++ = 0;

    // Empty user data block
	*cursor++ = 0;

	next_x = left_margin;
	
	// Additional controls
	for (i=0; i<num_buttons; i++)
	{
		ALIGN4(cursor);

		item_template = (DLGITEMTEMPLATE*) cursor;
		item_template->style = WS_CHILD | WS_VISIBLE;
		item_template->dwExtendedStyle = 0;
		item_template->x  = next_x;
		item_template->y  = top_margin + static_height + static_to_buttons_margin;
		item_template->cx = button_width;
		item_template->cy = button_height;
		item_template->id = ID_BASE + i;

		next_x += button_width + button_gap;

		// Move past DLGITEMTEMPLATE structure
		cursor = (WORD*)(item_template + 1);
   
		// Button class
		*cursor++ = 0xFFFF;
		*cursor++ = 0x0080;

		// Title
		wmemcpy(cursor, button_label[i], button_len[i]);
		cursor += button_len[i];
		*cursor++ = 0; 
  
		// Empty user data block
		*cursor++ = 0;             
	}

	ret_code = DialogBoxIndirect(GetModuleHandle(0), dlg_template, hWnd, NotificationDialogProc); 
    free(buf); 
    return ret_code; 
}
示例#10
0
static LRESULT
MultiInputDialog( HINSTANCE hinst, HWND hwndOwner,
                  char * ptext[], int numlines, int width,
                  int tb_cnt, struct textField * tb)
{
    HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWORD lpw;
    LPWSTR lpwsz;
    LRESULT ret;
    int nchar, i;
    size_t pwid;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 4096);
    if (!hgbl)
        return -1;

    mid_cnt = tb_cnt;
    mid_tb = tb;

    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);

    // Define a dialog box.

    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU
                   | DS_MODALFRAME | WS_CAPTION | DS_CENTER
                   | DS_SETFOREGROUND | DS_3DLOOK
                   | DS_SHELLFONT | DS_NOFAILCREATE;
    lpdt->cdit = numlines + (2 * tb_cnt) + 2;  // number of controls
    lpdt->x  = 10;
    lpdt->y  = 10;
    lpdt->cx = 20 + width * 4;
    lpdt->cy = 20 + (numlines + tb_cnt + 4) * 14;

    lpw = (LPWORD) (lpdt + 1);
    *lpw++ = 0;   // no menu
    *lpw++ = 0;   // predefined dialog box class (by default)

    lpwsz = (LPWSTR) lpw;
    nchar = MultiByteToWideChar (CP_ACP, 0, "", -1, lpwsz, 128);
    lpw   += nchar;
    *lpw++ = 8;                        // font size (points)
    lpwsz = (LPWSTR) lpw;
    nchar = MultiByteToWideChar (CP_ACP, 0, "MS Shell Dlg",
                                    -1, lpwsz, 128);
    lpw   += nchar;

    //-----------------------
    // Define an OK button.
    //-----------------------
    lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_BORDER;
    lpdit->dwExtendedStyle = 0;
    lpdit->x  = (lpdt->cx - 14)/4 - 20;
    lpdit->y  = 10 + (numlines + tb_cnt + 2) * 14;
    lpdit->cx = 40;
    lpdit->cy = 14;
    lpdit->id = IDOK;  // OK button identifier

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;    // button class

    lpwsz = (LPWSTR) lpw;
    nchar = MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50);
    lpw   += nchar;
    *lpw++ = 0;           // no creation data

    //-----------------------
    // Define an Cancel button.
    //-----------------------
    lpw = lpwAlign (lpw); // align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE) lpw;
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP | WS_BORDER;
    lpdit->dwExtendedStyle = 0;
    lpdit->x  = (lpdt->cx - 14)*3/4 - 20;
    lpdit->y  = 10 + (numlines + tb_cnt + 2) * 14;
    lpdit->cx = 40;
    lpdit->cy = 14;
    lpdit->id = IDCANCEL;  // CANCEL button identifier

    lpw = (LPWORD) (lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;    // button class

    lpwsz = (LPWSTR) lpw;
    nchar = MultiByteToWideChar (CP_ACP, 0, "Cancel", -1, lpwsz, 50);
    lpw   += nchar;
    *lpw++ = 0;           // no creation data

    /* Add controls for preface data */
    for ( i=0; i<numlines; i++) {
        /*-----------------------
         * Define a static text control.
         *-----------------------*/
        lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
        lpdit = (LPDLGITEMTEMPLATE) lpw;
        lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
        lpdit->dwExtendedStyle = 0;
        lpdit->x  = 10;
        lpdit->y  = 10 + i * 14;
        lpdit->cx = strlen(ptext[i]) * 4 + 10;
        lpdit->cy = 14;
        lpdit->id = ID_TEXT + i;  // text identifier

        lpw = (LPWORD) (lpdit + 1);
        *lpw++ = 0xFFFF;
        *lpw++ = 0x0082;                         // static class

        lpwsz = (LPWSTR) lpw;
        nchar = MultiByteToWideChar (CP_ACP, 0, ptext[i],
                                         -1, lpwsz, 2*width);
        lpw   += nchar;
        *lpw++ = 0;           // no creation data
    }

    for ( i=0, pwid = 0; i<tb_cnt; i++) {
        if ( pwid < strlen(tb[i].label) )
            pwid = strlen(tb[i].label);
    }

    for ( i=0; i<tb_cnt; i++) {
        /* Prompt */
        /*-----------------------
         * Define a static text control.
         *-----------------------*/
        lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
        lpdit = (LPDLGITEMTEMPLATE) lpw;
        lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;
        lpdit->dwExtendedStyle = 0;
        lpdit->x  = 10;
        lpdit->y  = 10 + (numlines + i + 1) * 14;
        lpdit->cx = pwid * 4;
        lpdit->cy = 14;
        lpdit->id = ID_TEXT + numlines + i;  // text identifier

        lpw = (LPWORD) (lpdit + 1);
        *lpw++ = 0xFFFF;
        *lpw++ = 0x0082;                         // static class

        lpwsz = (LPWSTR) lpw;
        nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].label ? tb[i].label : "",
                                     -1, lpwsz, 128);
        lpw   += nchar;
        *lpw++ = 0;           // no creation data

        /*-----------------------
         * Define an edit control.
         *-----------------------*/
        lpw = lpwAlign (lpw); /* align DLGITEMTEMPLATE on DWORD boundary */
        lpdit = (LPDLGITEMTEMPLATE) lpw;
        lpdit->style = WS_CHILD | WS_VISIBLE | ES_LEFT | WS_TABSTOP | WS_BORDER | (tb[i].echo == 1 ? 0L : ES_PASSWORD);
        lpdit->dwExtendedStyle = 0;
        lpdit->x  = 10 + (pwid + 1) * 4;
        lpdit->y  = 10 + (numlines + i + 1) * 14;
        lpdit->cx = (width - (pwid + 1)) * 4;
        lpdit->cy = 14;
        lpdit->id = ID_MID_TEXT + i;             // identifier

        lpw = (LPWORD) (lpdit + 1);
        *lpw++ = 0xFFFF;
        *lpw++ = 0x0081;                         // edit class

        lpwsz = (LPWSTR) lpw;
        nchar = MultiByteToWideChar (CP_ACP, 0, tb[i].def ? tb[i].def : "",
                                     -1, lpwsz, 128);
        lpw   += nchar;
        *lpw++ = 0;           // no creation data
    }

    GlobalUnlock(hgbl);
    ret = DialogBoxIndirect(hinst, (LPDLGTEMPLATE) hgbl,
							hwndOwner, (DLGPROC) MultiInputDialogProc);
    GlobalFree(hgbl);

    switch ( ret ) {
    case 0:     /* Timeout */
        return -1;
    case IDOK:
        return 1;
    case IDCANCEL:
        return 0;
    default: {
        char buf[256];
        sprintf(buf,"DialogBoxIndirect() failed: %d",GetLastError());
        MessageBox(hwndOwner,
                    buf,
                    "GetLastError()",
                    MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
        return -1;
    }
    }
}
示例#11
0
文件: gui_w16.c 项目: Stolas/vim-qt
    int
gui_mch_dialog(
    int		 type,
    char_u	*title,
    char_u	*message,
    char_u	*buttons,
    int		 dfltbutton,
    char_u	*textfield,
    int		ex_cmd)
{
    FARPROC	dp;
    LPWORD	p, pnumitems;
    int		numButtons;
    int		*buttonWidths, *buttonPositions;
    int		buttonYpos;
    int		nchar, i;
    DWORD	lStyle;
    int		dlgwidth = 0;
    int		dlgheight;
    int		editboxheight;
    int		horizWidth;
    int		msgheight;
    char_u	*pstart;
    char_u	*pend;
    char_u	*tbuffer;
    RECT	rect;
    HWND	hwnd;
    HDC		hdc;
    HFONT	oldFont;
    TEXTMETRIC	fontInfo;
    int		fontHeight;
    int		textWidth, minButtonWidth, messageWidth;
    int		maxDialogWidth;
    int		vertical;
    int		dlgPaddingX;
    int		dlgPaddingY;
    HGLOBAL	hglbDlgTemp;

#ifndef NO_CONSOLE
    /* Don't output anything in silent mode ("ex -s") */
    if (silent_mode)
	return dfltbutton;   /* return default option */
#endif

    /* If there is no window yet, open it. */
    if (s_hwnd == NULL && gui_mch_init() == FAIL)
	return dfltbutton;

    if ((type < 0) || (type > VIM_LAST_TYPE))
	type = 0;

    /* allocate some memory for dialog template */
    /* TODO should compute this really*/

    hglbDlgTemp = GlobalAlloc(GHND,  DLG_ALLOC_SIZE);
    if (hglbDlgTemp == NULL)
	return -1;

    p = (LPWORD) GlobalLock(hglbDlgTemp);

    if (p == NULL)
	return -1;

    /*
     * make a copy of 'buttons' to fiddle with it.  compiler grizzles because
     * vim_strsave() doesn't take a const arg (why not?), so cast away the
     * const.
     */
    tbuffer = vim_strsave(buttons);
    if (tbuffer == NULL)
	return -1;

    --dfltbutton;   /* Change from one-based to zero-based */

    /* Count buttons */
    numButtons = 1;
    for (i = 0; tbuffer[i] != '\0'; i++)
    {
	if (tbuffer[i] == DLG_BUTTON_SEP)
	    numButtons++;
    }
    if (dfltbutton >= numButtons)
	dfltbutton = 0;

    /* Allocate array to hold the width of each button */
    buttonWidths = (int *) lalloc(numButtons * sizeof(int), TRUE);
    if (buttonWidths == NULL)
	return -1;

    /* Allocate array to hold the X position of each button */
    buttonPositions = (int *) lalloc(numButtons * sizeof(int), TRUE);
    if (buttonPositions == NULL)
	return -1;

    /*
     * Calculate how big the dialog must be.
     */
    hwnd = GetDesktopWindow();
    hdc = GetWindowDC(hwnd);
    oldFont = SelectFont(hdc, GetStockObject(SYSTEM_FONT));
    dlgPaddingX = DLG_OLD_STYLE_PADDING_X;
    dlgPaddingY = DLG_OLD_STYLE_PADDING_Y;

    GetTextMetrics(hdc, &fontInfo);
    fontHeight = fontInfo.tmHeight;

    /* Minimum width for horizontal button */
    minButtonWidth = GetTextWidth(hdc, "Cancel", 6);

    /* Maximum width of a dialog, if possible */
    GetWindowRect(s_hwnd, &rect);
    maxDialogWidth = rect.right - rect.left
		     - GetSystemMetrics(SM_CXFRAME) * 2;
    if (maxDialogWidth < DLG_MIN_MAX_WIDTH)
	maxDialogWidth = DLG_MIN_MAX_WIDTH;

    /* Set dlgwidth to width of message */
    pstart = message;
    messageWidth = 0;
    msgheight = 0;
    do
    {
	pend = vim_strchr(pstart, DLG_BUTTON_SEP);
	if (pend == NULL)
	    pend = pstart + STRLEN(pstart);	/* Last line of message. */
	msgheight += fontHeight;
	textWidth = GetTextWidth(hdc, pstart, pend - pstart);
	if (textWidth > messageWidth)
	    messageWidth = textWidth;
	pstart = pend + 1;
    } while (*pend != NUL);
    dlgwidth = messageWidth;

    /* Add width of icon to dlgwidth, and some space */
    dlgwidth += DLG_ICON_WIDTH + 3 * dlgPaddingX;

    if (msgheight < DLG_ICON_HEIGHT)
	msgheight = DLG_ICON_HEIGHT;

    /*
     * Check button names.  A long one will make the dialog wider.
     */
	 vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
    if (!vertical)
    {
	// Place buttons horizontally if they fit.
	horizWidth = dlgPaddingX;
	pstart = tbuffer;
	i = 0;
	do
	{
	    pend = vim_strchr(pstart, DLG_BUTTON_SEP);
	    if (pend == NULL)
		pend = pstart + STRLEN(pstart);	// Last button name.
	    textWidth = GetTextWidth(hdc, pstart, pend - pstart);
	    if (textWidth < minButtonWidth)
		textWidth = minButtonWidth;
	    textWidth += dlgPaddingX;	    /* Padding within button */
	    buttonWidths[i] = textWidth;
	    buttonPositions[i++] = horizWidth;
	    horizWidth += textWidth + dlgPaddingX; /* Pad between buttons */
	    pstart = pend + 1;
	} while (*pend != NUL);

	if (horizWidth > maxDialogWidth)
	    vertical = TRUE;	// Too wide to fit on the screen.
	else if (horizWidth > dlgwidth)
	    dlgwidth = horizWidth;
    }

    if (vertical)
    {
	// Stack buttons vertically.
	pstart = tbuffer;
	do
	{
	    pend = vim_strchr(pstart, DLG_BUTTON_SEP);
	    if (pend == NULL)
		pend = pstart + STRLEN(pstart);	// Last button name.
	    textWidth = GetTextWidth(hdc, pstart, pend - pstart);
	    textWidth += dlgPaddingX;		/* Padding within button */
	    textWidth += DLG_VERT_PADDING_X * 2; /* Padding around button */
	    if (textWidth > dlgwidth)
		dlgwidth = textWidth;
	    pstart = pend + 1;
	} while (*pend != NUL);
    }

    if (dlgwidth < DLG_MIN_WIDTH)
	dlgwidth = DLG_MIN_WIDTH;	/* Don't allow a really thin dialog!*/

    /* start to fill in the dlgtemplate information.  addressing by WORDs */
    lStyle = DS_MODALFRAME | WS_CAPTION | WS_VISIBLE ;

    add_long(lStyle);
    pnumitems = p;	/*save where the number of items must be stored*/
    add_byte(0);	// NumberOfItems(will change later)
    add_word(10);	// x
    add_word(10);	// y
    add_word(PixelToDialogX(dlgwidth));

    // Dialog height.
    if (vertical)
	dlgheight = msgheight + 2 * dlgPaddingY +
			      DLG_VERT_PADDING_Y + 2 * fontHeight * numButtons;
    else
	dlgheight = msgheight + 3 * dlgPaddingY + 2 * fontHeight;

    // Dialog needs to be taller if contains an edit box.
    editboxheight = fontHeight + dlgPaddingY + 4 * DLG_VERT_PADDING_Y;
    if (textfield != NULL)
	dlgheight += editboxheight;

    add_word(PixelToDialogY(dlgheight));

    add_byte(0);	//menu
    add_byte(0);	//class

    /* copy the title of the dialog */
    add_string(title ? title : ("Vim"VIM_VERSION_MEDIUM));

    buttonYpos = msgheight + 2 * dlgPaddingY;

    if (textfield != NULL)
	buttonYpos += editboxheight;

    pstart = tbuffer; //dflt_text
    horizWidth = (dlgwidth - horizWidth) / 2;	/* Now it's X offset */
    for (i = 0; i < numButtons; i++)
    {
	/* get end of this button. */
	for (	pend = pstart;
		*pend && (*pend != DLG_BUTTON_SEP);
		pend++)
	    ;

	if (*pend)
	    *pend = '\0';

	/*
	 * NOTE:
	 * setting the BS_DEFPUSHBUTTON style doesn't work because Windows sets
	 * the focus to the first tab-able button and in so doing makes that
	 * the default!! Grrr.  Workaround: Make the default button the only
	 * one with WS_TABSTOP style. Means user can't tab between buttons, but
	 * he/she can use arrow keys.
	 *
	 * NOTE (Thore): Setting BS_DEFPUSHBUTTON works fine when it's the
	 * first one, so I changed the correct button to be this style. This
	 * is necessary because when an edit box is added, we need a button to
	 * be default.  The edit box will be the default control, and when the
	 * user presses enter from the edit box we want the default button to
	 * be pressed.
	 */
	if (vertical)
	{
	    p = add_dialog_element(p,
		    ((i == dfltbutton || dfltbutton < 0) && textfield != NULL
			    ?  BS_DEFPUSHBUTTON : BS_PUSHBUTTON) | WS_TABSTOP,
		    PixelToDialogX(DLG_VERT_PADDING_X),
		    PixelToDialogY(buttonYpos /* TBK */
				   + 2 * fontHeight * i),
		    PixelToDialogX(dlgwidth - 2 * DLG_VERT_PADDING_X),
		    (WORD)(PixelToDialogY(2 * fontHeight) - 1),
		    (WORD)(IDCANCEL + 1 + i), (BYTE)0x80, pstart);
	}
	else
	{
	    p = add_dialog_element(p,
		    ((i == dfltbutton || dfltbutton < 0) && textfield != NULL
			     ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON) | WS_TABSTOP,
		    PixelToDialogX(horizWidth + buttonPositions[i]),
		    PixelToDialogY(buttonYpos), /* TBK */
		    PixelToDialogX(buttonWidths[i]),
		    (WORD)(PixelToDialogY(2 * fontHeight) - 1),
		    (WORD)(IDCANCEL + 1 + i), (BYTE)0x80, pstart);
	}

	pstart = pend + 1;	/*next button*/

    }
    *pnumitems += numButtons;

    /* Vim icon */
    p = add_dialog_element(p, SS_ICON,
	    PixelToDialogX(dlgPaddingX),
	    PixelToDialogY(dlgPaddingY),
	    PixelToDialogX(DLG_ICON_WIDTH),
	    PixelToDialogY(DLG_ICON_HEIGHT),
	    DLG_NONBUTTON_CONTROL + 0, (BYTE)0x82,
	    &dlg_icons[type]);


    /* Dialog message */
    p = add_dialog_element(p, SS_LEFT,
	    PixelToDialogX(2 * dlgPaddingX + DLG_ICON_WIDTH),
	    PixelToDialogY(dlgPaddingY),
	    (WORD)(PixelToDialogX(messageWidth) + 1),
	    PixelToDialogY(msgheight),
	    DLG_NONBUTTON_CONTROL + 1, (BYTE)0x82, message);

    /* Edit box */
    if (textfield != NULL)
    {
	p = add_dialog_element(p, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP | WS_BORDER,
		PixelToDialogX(2 * dlgPaddingX),
		PixelToDialogY(2 * dlgPaddingY + msgheight),
		PixelToDialogX(dlgwidth - 4 * dlgPaddingX),
		PixelToDialogY(fontHeight + dlgPaddingY),
		DLG_NONBUTTON_CONTROL + 2, (BYTE)0x81, textfield);
	*pnumitems += 1;
    }

    *pnumitems += 2;

    SelectFont(hdc, oldFont);
    ReleaseDC(hwnd, hdc);
    dp = MakeProcInstance((FARPROC)dialog_callback, s_hinst);


    /* Let the dialog_callback() function know which button to make default
     * If we have an edit box, make that the default. We also need to tell
     * dialog_callback() if this dialog contains an edit box or not. We do
     * this by setting s_textfield if it does.
     */
    if (textfield != NULL)
    {
	dialog_default_button = DLG_NONBUTTON_CONTROL + 2;
	s_textfield = textfield;
    }
    else
    {
	dialog_default_button = IDCANCEL + 1 + dfltbutton;
	s_textfield = NULL;
    }

    /*show the dialog box modally and get a return value*/
    nchar = DialogBoxIndirect(
	    s_hinst,
	    (HGLOBAL) hglbDlgTemp,
	    s_hwnd,
	    (DLGPROC)dp);

    FreeProcInstance( dp );
    GlobalUnlock(hglbDlgTemp);
    GlobalFree(hglbDlgTemp);
    vim_free(tbuffer);
    vim_free(buttonWidths);
    vim_free(buttonPositions);


    return nchar;
}