Tôi có một hộp kiểm mà tôi muốn đo chính xác để tôi có thể định vị các điều khiển trên hộp thoại chính xác. Tôi có thể dễ dàng đo kích thước của văn bản trên điều khiển - nhưng tôi không biết cách "chính thức" tính toán kích thước của hộp kiểm và khoảng cách trước (hoặc sau) văn bản.Làm thế nào để có được kích thước của kiểm tra và khoảng cách trong hộp kiểm?
Trả lời
Tôi chắc rằng chiều rộng của hộp kiểm tương đương với
int x = GetSystemMetrics(SM_CXMENUCHECK);
int y = GetSystemMetrics(SM_CYMENUCHECK);
Sau đó bạn có thể làm việc ra khu vực bên trong bằng cách trừ đi sau ...
int xInner = GetSystemMetrics(SM_CXEDGE);
int yInner = GetSystemMetrics(SM_CYEDGE);
tôi sử dụng trong mã của tôi và chưa có sự cố ...
Mã này không hoạt động trên Win7 với giao diện người dùng được chia tỷ lệ (phông chữ lớn hơn 125% hoặc lớn hơn 150%). Điều duy nhất dường như hoạt động là:
int WID = 13 * dc.GetDeviceCaps(LOGPIXELSX)/96;
int HEI = 13 * dc.GetDeviceCaps(LOGPIXELSY)/96;
Thật đáng tiếc là Microsoft không cung cấp cách để biết điều này chắc chắn. Tôi đã đấu tranh với cùng một câu hỏi và câu trả lời được cung cấp ở trên chưa hoàn chỉnh. Vấn đề chính với nó là nếu phông chữ của cửa sổ hộp thoại được đặt thành một cái gì đó khác với kích thước mặc định, giải pháp đó sẽ không hoạt động vì các hộp kiểm sẽ được thay đổi kích thước.
Đây là cách tôi giải quyết vấn đề này (nó chỉ là một xấp xỉ mà dường như đã làm việc cho tôi). Mã cho dự án MFC.
1 - Tạo hai điều khiển thử nghiệm trên mẫu của bạn, một hộp kiểm và một hộp radio:
2 - Xác định cấu trúc tùy chỉnh sau:
struct CHECKBOX_DIMS{
int nWidthPx;
int nHeightPx;
int nSpacePx; //Space between checkbox and text
CHECKBOX_DIMS()
{
nWidthPx = 0;
nHeightPx = 0;
nSpacePx = 0;
}
};
3 - Gọi đến sau mã khi biểu mẫu khởi tạo cho từng điều khiển kiểm tra (sẽ đo lường chúng và loại bỏ chúng để người dùng cuối dường như không có chúng):
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 - Bây giờ bạn có thể dễ dàng thay đổi kích thước bất kỳ hộp kiểm hoặc radio hộp bằng cách gọi này:
//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;
}
Câu trả lời ngắn:
Version dài
Từ MSDN Layout Specifications: Win32, chúng tôi có thông số kỹ thuật về kích thước của hộp kiểm.
Đó là 12 đơn vị thoại từ cạnh trái của điều khiển để bắt đầu của văn bản:
Và một điều khiển hộp kiểm là 10 đơn vị thoại cao:
Surfaces and Controls Height (DLUs) Width (DLUs)
===================== ============= ===========
Check box 10 As wide as possible (usually to the margins) to accommodate localization requirements.
Trước tiên, chúng tôi tính toán kích thước của đơn vị hộp thoại ngang và dọc:
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);
Sử dụng chức năng helper ích:
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;
}
Bây giờ chúng ta biết có bao nhiêu pixel (checkboxSpacing
) để thêm, chúng tôi tính toán kích thước nhãn như bình thường:
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;
Lưu ý: Bất kỳ mã nào được phát hành vào miền công cộng. Không yêu cầu ghi nhận tác giả.
Ok dudes cách của tôi có thể không phải là fastes để sử dụng trong thời gian chạy, nhưng nó hoạt động cho tôi trong mọi trường hợp tôi đã thử nghiệm cho đến nay. Trong sự bắt của proggys của tôi đưa vào một chức năng để có được kích thước và lưu nó trong một biến toàn cục (yeah tôi đã nghe nói đây sẽ là xấu, nhưng tôi không quan tâm về điều này)
đây giải thích:
- Tạo một treeview (vô hình nếu u muốn)
- Tạo một imagelist với ít nhất 1 hình ảnh bên trong (kích thước 16x16)
- Đặt imagelist vào treeview ("TVSIL_NORMAL")
- Lấy "TVSIL_STATE" imagelist từ treeview (u phải tạo ra " TVSIL_NORMAL "trước đây, nếu không điều này sẽ thất bại!)
- Sử dụng ImageList_GetIconSize (..) và lưu trữ kích thước. Ồ, các hộp kiểm và các nút radio có cùng kích thước với các biểu tượng trạng thái của ảnh treeview. Bây giờ bạn có những gì bạn muốn!
- Phá hủy "TVSIL_NORMAL" imagelist
- Phá hủy treeview
mã này chỉ cần một vài micro vào đầu proggies của tôi và tôi có thể sử dụng mọi giá trị tôi cần nó.
Preamble:
Tôi có cùng một câu hỏi trong khi cố gắng để xác định kích thước cần thiết của việc kiểm soát hộp kiểm cho một văn bản nhất định và phát hiện ra rằng câu trả lời hiện không thực sự làm việc cho tôi, vì nhiều lý do:
SM_CXMENUCHECK
không tính đến khoảng trống. Trong thực tế, tôi không thuyết phục điều này là ngay cả đối với các hộp kiểm thông thường, mặc dù nó có thể có cùng giá trị. Nó cũng có thể phụ thuộc vào phong cách trực quan được kích hoạt.- Các câu trả lời khác quá phức tạp và cảm thấy một chút khó khăn (không tôn trọng dự định, đó là MS mà không làm cho điều này dễ dàng).
- Bố cục 12DLU đã nêu là rất hữu ích, mặc dù lại cảm thấy tùy ý mà không có số liệu hệ thống dựa vào.
- Câu trả lời tôi đã thử vẫn không mang lại giá trị pixel đủ cao để ngăn văn bản hộp kiểm khỏi gói.
Điều tra của tôi:
Tôi đã xem cách Wine tái tạo hành vi và nhận được kết quả tương tự như giả định 12DLU. Tuy nhiên, văn bản vẫn được bao bọc trừ khi tôi thêm 3 pixel vào chiều rộng (mặc dù văn bản phải vừa vặn mà không có). Tôi cũng nhận thấy rằng GetTextExtentPoint32
mang lại giá trị là 3 cho một chuỗi trống (hmmm ...)
Tắt kiểu BS_MULTILINE
rõ ràng là đã dừng gói văn bản. My guess là các tính toán gói từ DrawTextW
là không hoàn hảo.
Tại thời điểm này, tôi quyết định rằng giải pháp đơn giản nhất là chỉ thêm 1 khoảng trống cho GetTextExtentPoint32
, để chắc chắn sẽ có đủ pixel. Tôi đã ước tính quá mức một vài pixel.
Lưu ý rằng tất cả điều này giả định rằng ứng dụng của bạn được thể hiện dưới dạng DPI. Nếu không, tôi thấy hộp kiểm xuất hiện lớn hơn nhiều trên một số hệ thống Windows 7 (không phải tất cả).
My (chủ yếu là rượu của) giải pháp:
// 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);
- 1. Làm thế nào để kiểm soát kích thước của hộp chọn trong Ruby on Rails 3?
- 2. Làm thế nào để kiểm tra kích thước của một phao trong python?
- 3. Thay đổi kích thước của hộp kiểm và dấu kiểm trong đó
- 4. Làm cách nào để thay đổi kích thước hoặc màu của hộp kiểm xoay vòng?
- 5. Làm thế nào để kiểm tra kích thước của tệp được tải lên một cách an toàn trong bottlepy?
- 6. Trong Python, làm cách nào để kiểm tra kích thước của đối tượng StringIO?
- 7. Làm cách nào để kiểm tra kích thước tệp trong tập lệnh batch của Windows?
- 8. Làm thế nào để đọc nếu một hộp kiểm được kiểm tra trong PHP?
- 9. Làm cách nào để tăng khoảng cách giữa hộp kiểm và văn bản được liên kết?
- 10. kiểm tra jquery nếu hộp kiểm asp được kiểm tra
- 11. Kiểm tra xem hộp kiểm có được chọn với jQuery
- 12. Làm cách nào để kiểm tra kích thước đầu vào của tệp bằng jQuery?
- 13. Có cách nào để ngăn Hộp kiểm WPF kích hoạt sự kiện Đã kiểm tra của nó không?
- 14. NSFileManager - Kiểm tra kích thước tệp?
- 15. Cách kiểm tra kích thước tệp trong python?
- 16. Kiểm tra xem hộp kiểm 'này' có được kiểm tra là
- 17. Làm thế nào để kiểm tra kích thước bộ sưu tập trong JPA2
- 18. Cách đếm số hộp kiểm đã được kiểm tra
- 19. FDF - cách kiểm tra hộp kiểm?
- 20. Làm cách nào để xác minh xem hộp kiểm có được kiểm tra trong một Delphi TTaskDialog không?
- 21. Cách kiểm tra kích thước tệp khi tải lên
- 22. Làm cách nào tôi có thể kiểm tra nhiều hộp kiểm trong jQuery?
- 23. Làm thế nào để chọn trước hộp kiểm trong angularJs với ng-kiểm tra
- 24. Làm cách nào để tạo hộp kiểm nhỏ hơn kích thước mặc định?
- 25. Làm cách nào để xem hộp kiểm nào được chọn?
- 26. HashMap đồng thời: kiểm tra kích thước
- 27. Backbone.js - Cách tốt nhất để kiểm tra hộp kiểm
- 28. Django: Làm thế nào để kiểm tra xem widget trường là hộp kiểm trong mẫu?
- 29. Kiểm tra hộp kiểm jQuery/bỏ chọn
- 30. Kiểm tra nếu hộp kiểm đã được kiểm tra trên tải sử dụng jQuery
Dường như làm việc tốt cho tôi :) (? Odd như thế nào đó là "kiểm tra menu" và không có một lựa chọn cho một hộp kiểm tra thường xuyên) –
tôi biết đó là một chủ đề cũ, tôi đã tìm thấy nó qua Google. Thật không may câu trả lời này không hoàn toàn chính xác. Xem giải thích của tôi dưới đây ... – c00000fd