मैं एक चेक बॉक्स है कि मैं सही ढंग से मापने के लिए तो मैं सही ढंग से एक संवाद पर नियंत्रण रख सकते हैं चाहते हैं। मैं आसानी से नियंत्रण पर पाठ का आकार माप सकते हैं - लेकिन मैं चेक बॉक्स के आकार और इससे पहले कि (या बाद) पाठ अंतराल की गणना के आधिकारिक जिस तरह से पता नहीं है।
कैसे की जांच और चेक बॉक्स में अंतर आकार पाने के लिए?
मैं बहुत यकीन है कि चेकबॉक्स की चौड़ाई के बराबर होता है कर रहा हूँ
int x = GetSystemMetrics( SM_CXMENUCHECK );
int y = GetSystemMetrics( SM_CYMENUCHECK );
इसके बाद आप निम्नलिखित को घटा कर अंदर क्षेत्र बाहर काम कर सकते हैं ...
int xInner = GetSystemMetrics( SM_CXEDGE );
int yInner = GetSystemMetrics( SM_CYEDGE );
मैं का उपयोग अपने कोड में है कि और इस प्रकार अब तक एक समस्या नहीं पड़ा है ...
इस कोड को बढ़ाया यूआई (फोंट 125% बड़ा या 150% बड़ा) के साथ Win7 पर काम नहीं करता। केवल एक चीज है काम करने के लिए लगता है कि यह है:
int WID = 13 * dc.GetDeviceCaps(LOGPIXELSX) / 96;
int HEI = 13 * dc.GetDeviceCaps(LOGPIXELSY) / 96;
यह शर्म की बात है कि माइक्रोसॉफ्ट एक तरीका यह सुनिश्चित करने के लिए इस पता करने के लिए नहीं प्रदान की थी है। मैं एक ही सवाल के साथ संघर्ष कर रहा था और ऊपर दिया जवाब पूरा नहीं हुआ है। इसके साथ मुख्य समस्या यह है कि संवाद विंडो के फ़ॉन्ट डिफ़ॉल्ट आकार के अलावा कुछ करने के लिए सेट है, तो यह है कि समाधान क्योंकि चेक बॉक्स बदल दिया जाएगा काम नहीं करेगा है।
यहाँ कैसे मैं इस मुद्दे को हल (यह सिर्फ एक सन्निकटन है कि मेरे लिए काम किया है लगता है) है। कोड MFC परियोजना के लिए है।
1 - अपने फार्म, एक चेकबॉक्स और एक रेडियो बॉक्स पर दो परीक्षण नियंत्रण बनाएँ:

2 - निम्न कस्टम struct को परिभाषित करें:
struct CHECKBOX_DIMS{
int nWidthPx;
int nHeightPx;
int nSpacePx; //Space between checkbox and text
CHECKBOX_DIMS()
{
nWidthPx = 0;
nHeightPx = 0;
nSpacePx = 0;
}
};
3 - जब प्रपत्र परीक्षण नियंत्रण के प्रत्येक (कि उन्हें मापने और उन्हें हटाने के लिए इतना है कि अंत उपयोगकर्ताओं के लिए उन्हें नहीं लग रहे हो जाएगा) के लिए initializes निम्नलिखित कोड कॉल करें:
BOOL OnInitDialog()
{
CDialog::OnInitDialog();
//Calculate the size of a checkbox & radio box
VERIFY(GetInitialCheckBoxSize(IDC_CHECK_TEST, &dimsCheckBox, TRUE));
VERIFY(GetInitialCheckBoxSize(IDC_RADIO_TEST, &dimsRadioBox, TRUE));
//Continue with form initialization ...
}
BOOL GetInitialCheckBoxSize(UINT nCtrlID, CHECKBOX_DIMS* pOutCD, BOOL bRemoveCtrl)
{
//Must be called initially to calculate the size of a checkbox/radiobox
//'nCtrlID' = control ID to measure
//'pOutCD' = if not NULL, receives the dimensitions
//'bRemoveCtrl' = TRUE to delete control
//RETURN:
// = TRUE if success
BOOL bRes = FALSE;
//Get size of a check (not exactly what we need)
int nCheckW = GetSystemMetrics(SM_CXMENUCHECK);
int nCheckH = GetSystemMetrics(SM_CYMENUCHECK);
//3D border spacer (not exactly what we need either)
int nSpacerW = GetSystemMetrics(SM_CXEDGE);
//Get test checkbox
CButton* pChkWnd = (CButton*)GetDlgItem(nCtrlID);
ASSERT(pChkWnd);
if(pChkWnd)
{
CRect rcCheckBx;
pChkWnd->GetWindowRect(&rcCheckBx);
//We need only the height
//INFO: The reason why we can't use the width is because there's
// an arbitrary text followed by a spacer...
int h = rcCheckBx.Height();
CDC* pDc = pChkWnd->GetDC();
if(pDc)
{
//Get horizontal DPI setting
int dpiX = pDc->GetDeviceCaps(LOGPIXELSX);
//Calculate
if(pOutCD)
{
//Use height as-is
pOutCD->nHeightPx = h;
//Use height for the width
pOutCD->nWidthPx = (int)(h * ((double)nCheckW / nCheckH));
//Spacer is the hardest
//INFO: Assume twice and a half the size of 3D border &
// take into account DPI setting for the window
// (It will give some extra space, but it's better than less space.)
// (This number is purely experimental.)
// (96 is Windows DPI setting for 100% resolution setting.)
pOutCD->nSpacePx = (int)(nSpacerW * 2.5 * dpiX / 96.0);
}
//Release DC
pChkWnd->ReleaseDC(pDc);
if(bRemoveCtrl)
{
//Delete window
bRes = pChkWnd->DestroyWindow();
}
else
{
//Keep the window
bRes = TRUE;
}
}
}
return bRes;
}
4 - अब आप आसानी से किसी भी चेकबॉक्स या रेडियो बॉक्स इस फोन करके आकार बदल सकते हैं:
//Set checkbox size & new text
VERIFY(SetCheckBoxTextAndSize(this, IDC_CHECK_ID, &dimsCheckBox, L"New text") > 0);
//Just resize radio box
VERIFY(SetCheckBoxTextAndSize(this, IDC_RADIO_ID, &dimsRadioBox, NULL) > 0);
int SetCheckBoxTextAndSize(CWnd* pParWnd, UINT nCheckBoxID, CHECKBOX_DIMS* pDims, LPCTSTR pNewText)
{
//Set size of the checkbox/radio to 'pNewText' and update its size according to its text
//'pParWnd' = parent dialog window
//'nCheckBoxID' = control ID to resize (checkbox or radio box)
//'pDims' = pointer to the struct with checkbox/radiobox dimensions
//'pNewText' = text to set, or NULL not to change the text
//RETURN:
// = New width of the control in pixels, or
// = 0 if error
int nRes = 0;
ASSERT(pParWnd);
ASSERT(pDims);
CButton* pChkWnd = (CButton*)pParWnd->GetDlgItem(nCheckBoxID);
ASSERT(pChkWnd);
if(pChkWnd)
{
CDC* pDc = pChkWnd->GetDC();
CFont* pFont = pChkWnd->GetFont();
if(pDc)
{
if(pFont)
{
//Make logfont
LOGFONT lf = {0};
if(pFont->GetLogFont(&lf))
{
//Make new font
CFont font;
if(font.CreateFontIndirect(&lf))
{
//Get font from control
CFont* pOldFont = pDc->SelectObject(&font);
//Get text to set
CString strCheck;
if(pNewText)
{
//Use new text
strCheck = pNewText;
}
else
{
//Keep old text
pChkWnd->GetWindowText(strCheck);
}
//Calculate size
RECT rc = {0, 0, 0, 0};
::DrawText(pDc->GetSafeHdc(), strCheck, strCheck.GetLength(), &rc, DT_CALCRECT | DT_NOPREFIX | DT_SINGLELINE);
//Get text width
int nTextWidth = abs(rc.right - rc.left);
//See if it's valid
if(nTextWidth > 0 ||
(nTextWidth == 0 && strCheck.GetLength() == 0))
{
//Get location of checkbox
CRect rcChk;
pChkWnd->GetWindowRect(&rcChk);
pParWnd->ScreenToClient(rcChk);
//Update its size
rcChk.right = rcChk.left + pDims->nWidthPx + pDims->nSpacePx + nTextWidth;
//Use this line if you want to change the height as well
//rcChk.bottom = rcChk.top + pDims->nHeightPx;
//Move the control
pChkWnd->MoveWindow(rcChk);
//Setting new text?
if(pNewText)
{
pChkWnd->SetWindowText(pNewText);
}
//Done
nRes = abs(rcChk.right - rcChk.left);
}
//Set font back
pDc->SelectObject(pOldFont);
}
}
}
//Release DC
pChkWnd->ReleaseDC(pDc);
}
}
return nRes;
}
संक्षिप्त जवाब:

दीर्घ संस्करण
से MSDN लेआउट विनिर्देश: Win32 , हम एक चेकबॉक्स के आयामों की विशिष्टताओं की है।
यह है 12 संवाद इकाइयों टेक्स्ट की शुरुआत करने के लिए नियंत्रण के बाएं किनारे से:

और एक चेकबॉक्स नियंत्रण 10 संवाद इकाइयों लंबा है:
Surfaces and Controls Height (DLUs) Width (DLUs)
===================== ============= ===========
Check box 10 As wide as possible (usually to the margins) to accommodate localization requirements.
पहले हम एक क्षैतिज और एक ऊर्ध्वाधर संवाद इकाई के आकार की गणना:
const dluCheckBoxInternalSpacing = 12; //12 horizontal dlus
const dluCheckboxHeight = 10; //10 vertical dlus
Size dialogUnits = GetAveCharSize(dc);
Integer checkboxSpacing = MulDiv(dluCheckboxSpacing, dialogUnits.Width, 4);
Integer checkboxHeight = MulDiv(dluCheckboxHeight, dialogUnits.Height, 8);
काम सहायक समारोह का उपयोग करना:
Size GetAveCharSize(HDC dc)
{
/*
How To Calculate Dialog Base Units with Non-System-Based Font
http://support.microsoft.com/kb/125681
*/
TEXTMETRIC tm;
GetTextMetrics(dc, ref tm);
String buffer = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Size result;
GetTextExtentPoint32(dc, buffer, 52, out result);
result.Width = (result.X/26 + 1) / 2; //div uses trunc rounding; we want arithmetic rounding
result.Height = tm.tmHeight;
return result;
}
अब हम कितने पिक्सल (पता है कि checkboxSpacing) जोड़ने के लिए, हम सामान्य रूप में लेबल आकार की गणना:
textRect = Rect(0,0,0,0);
DrawText(dc, Caption, -1, textRect, DT_CALCRECT or DT_LEFT or DT_SINGLELINE);
chkVerification.Width = checkboxSpacing+textRect.Right;
chkVerification.Height = checkboxHeight;

नोट : सार्वजनिक डोमेन में जारी किया गया कोई भी कोड। कोई विशेषता आवश्यक है।
ठीक है दोस्तों मेरे रास्ते शायद fastes क्रम में उपयोग करने के लिए नहीं है, लेकिन यह किसी भी मामले मैं अब तक का परीक्षण किया है में मेरे लिए काम करता है। मेरी proggys की beginnin में मैं एक समारोह में डाल आकार मिलता है और (हाँ मैंने सुना है यह बुरा होगा, लेकिन मैं इस बारे में ध्यान न) एक वैश्विक चर में संग्रहीत करना
स्पष्टीकरण:
- एक treeview बनाएँ (अदृश्य यदि u चाहते हैं)
- कम से कम 1 छवि के अंदर (आकार 16x16) के साथ एक छवि बनाएं
- treeview ( "TVSIL_NORMAL") के ImageList सेट
- treeview से "TVSIL_STATE" ImageList जाओ (यू "TVSIL_NORMAL" से पहले बनाने के लिए, अन्यथा यह एक असफल हो जायेगी!)
- ImageList_GetIconSize (..) का प्रयोग करें और आकार की दुकान। वाह, checkboxs और रेडियो बटन treeview के राज्य प्रतीक के रूप में एक ही आकार की है। अब यू यू क्या चाहते है!
- "TVSIL_NORMAL" ImageList नष्ट
- treeview नष्ट
इस कोड को मेरी proggies की शुरुआत में केवल कुछ ही माइक्रोसेकंड की जरूरत है और मैं मूल्य हर मैं इसे जरूरत उपयोग कर सकते हैं।
प्रस्तावना:
मैं एक ही सवाल दिए गए पाठ के लिए चेकबॉक्स नियंत्रण की जरूरत आकार तय करने के प्रयास किया था और पाया कि मौजूदा जवाब वास्तव में कई कारणों से, मेरे लिए काम नहीं किया:
SM_CXMENUCHECKखाई के लिए खाते में नहीं है। वास्तव में, मैं आश्वस्त नहीं कर रहा हूँ इस नियमित चेक बॉक्स के लिए भी है, हालांकि यह एक ही मूल्य है हो सकता है। यह भी निर्भर पर दृश्य शैलियों सक्षम किया जा रहा हो सकता है।- अन्य उत्तर overly जटिल थे और थोड़ा hacky महसूस किया (कोई अनादर इरादा है, यह एमएस कि यह आसान नहीं बनाते हैं) है।
- कहा गया है 12DLU लेआउट, बहुत मददगार था, हालांकि फिर से एक प्रणाली पर भरोसा करने मीट्रिक बिना मनमाने ढंग से लगता है।
- जवाब मैं अभी भी करने की कोशिश की एक पर्याप्त उच्च पिक्सेल मूल्य उपज नहीं था रैपिंग से चेकबॉक्स पाठ को रोकने के लिए।
मेरे जांच:
मैं कैसे शराब व्यवहार reproduces देख कर पाया है यह भी बस 12DLU संभालने रूप में एक ही परिणाम देता है कि। हालांकि, पाठ अभी भी लपेटा जब तक कि मैं चौड़ाई (भले ही पाठ के बिना ठीक से फिट होना चाहिए) के लिए एक अतिरिक्त 3 पिक्सल गयी। मैं यह भी देखा कि GetTextExtentPoint32एक खाली स्ट्रिंग (हममम ...) के लिए 3 के एक मूल्य की पैदावार
को बंद करने से BS_MULTILINEशैली स्पष्ट रूप से टेक्स्ट रैपिंग बंद कर दिया। मेरे अनुमान है कि है DrawTextWकी शब्द रैपिंग गणना अपूर्ण हैं।
इस बिंदु पर मैंने तय कर लिया है कि सरल समाधान सिर्फ 1 अतिरिक्त स्थान में जोड़ने के लिए था GetTextExtentPoint32, ताकि निश्चित रूप से पर्याप्त पिक्सल होगा। पिक्सल के एक जोड़े की ओवर-द अनुमान मेरे लिए स्वीकार्य है।
ध्यान दें कि यह सब हो जाती है आपके आवेदन डीपीआई बारे में पता के रूप में प्रकट होता है। अन्यथा मैंने पाया चेकबॉक्स दिखाई दिया कुछ विंडोज 7 सिस्टम (सभी हालांकि नहीं) पर बहुत बड़ा।
मेरे (ज्यादातर शराब के) समाधान:
// This code gets the size of a piece of text and adds the size of a
// checkbox and gap. Note that this is very rough code with no error handling.
BOOL isCheckbox = TRUE;
HWND dialog = ... // Your control or dialog
HFONT font = ... // The font your control will use if it hasn't been set yet
PTCHAR text = ... // Your text
HFONT currentFont;
SIZE size;
HDC dc = GetDC(dialog);
if (!font) {
font = (HFONT)SendMessage(dialog, WM_GETFONT, 0, 0);
}
currentFont = (HFONT)SelectObject(dc, font); // NB: You should add error handling here
if (isCheckbox) {
// Or you can disable BS_MULTILINE
_tcscat(text, TEXT(" ")); // NB: This assumes text is allocated for +1 char
}
GetTextExtentPoint32(dc, text, _tcslen(text), &size); // NB: You should add error handling here
if (isCheckbox) {
int checkBoxWidth = 12 * GetDeviceCaps(dc, LOGPIXELSX ) / 96 + 1;
int checkBoxHeight = 12 * GetDeviceCaps(dc, LOGPIXELSY ) / 96 + 1;
int textOffset;
GetCharWidthW(dc, '0', '0', &textOffset);
textOffset /= 2;
size->cx += checkBoxWidth + textOffset;
if (size->cy < checkBoxHeight) {
size->cy = checkBoxHeight;
}
}
if (currentFont) {
SelectObject(dc, currentFont);
}
ReleaseDC(dialog, dc);
क्षमा करें यह पुराने धागा पुनर्जीवित करने के लिए। मैं हाल ही में अपने आप ठीक उसी प्रश्न के बारे में सोच पाया। वर्तमान में, जवाब में से कोई भी ऊपर एक परिणाम Windows 10 के साथ संगत अलग फोंट और फ़ॉन्ट आकार, विशेष रूप से उच्च डीपीआई के वातावरण में के लिए दे।
इसके बजाय, ऐसा लगता है कि सही परिणाम प्राप्त किया गया है
SIZE szCheckBox;
GetThemePartSize(hTheme, hDC, BP_CHECKBOX, CBS_UNCHECKEDNORMAL, &rcBackgroundContent, TS_TRUE, &szCheckBox);
चेकबॉक्स खुद के आकार के लिए। तथा
SIZE szZeroCharacter;
GetTextExtentPoint32(hDC, L"0", 1, &szZeroCharacter);
int iGapWidth = szZeroCharacter.cx / 2;
अंतर की चौड़ाई के लिए। ऊपर पदों से प्रेरित विभिन्न तरीकों का एक बहुत कोशिश के बाद, मैंने पाया L"0"comctl32.dll की dissembly में। और जब यह मेरे लिए एक मजाक (जरूरी नहीं एक अच्छा एक) की तरह दिखता है, मुझे लगता है यह पुराने दिनों से पकड़ मिली थी जब इस 2DLU का एक अच्छा पर्याप्त सन्निकटन गया हो सकता है है।
अस्वीकरण: जब मैं Windows 10 पर विभिन्न फोंट और विभिन्न आकारों के साथ परिणाम परीक्षण किया है, इस बात की पुष्टि करने के लिए कि यह भी ऑपरेटिंग सिस्टम के किसी भी अन्य (पुराने) संस्करण पर धारण करने का प्रयास नहीं किया है।













