Programim dhe zhvillim, javascript, python, php, html

C++ Merrni pozicionin dhe madhësinë e një kontrolli dialogu

Unë jam duke përdorur Visual Studio 2015 C++ dhe kam një kuti dialogu të përcaktuar në një skedar .rc:

IDD_SERIALCTRLDEMO_DIALOG DIALOGEX 0, 0, 313, 164
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "SerialCtrlDemo"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    LTEXT           "Serial Number:",IDC_STATIC,14,10,48,8
    COMBOBOX        IDC_COMBO_SN,66,8,48,55,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Baud Rate:",IDC_STATIC,135,10,37,8
    COMBOBOX        IDC_COMBO_BR,176,8,48,55,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
    LTEXT           "Read:",IDC_STATIC,11,51,20,8
    PUSHBUTTON      "Open",IDC_BUTTON_OPEN,242,7,50,14
    LISTBOX         IDC_LIST_READ,11,62,23,76,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    EDITTEXT        IDC_EDIT_WRITE,11,34,237,14,ES_AUTOHSCROLL
    PUSHBUTTON      "Write",IDC_BUTTON_WR,252,33,46,14
    GROUPBOX        "",IDC_STATIC,7,0,294,25
    GROUPBOX        "",IDC_STATIC,7,26,296,117
    LTEXT           "",IDC_STATIC_INFO,11,150,287,8
    CONTROL         "",IDC_SENSOR,"Static",SS_BLACKRECT,41,62,256,76
END

enter code here

Kontrolli që më intereson është kutia e fotografive "IDC_SENSOR" (hyrja e fundit), e cila është përcaktuar në/si 41,62,256,76. Por në ekran, përmasat janë të ndryshme, ndoshta për shkak të Paraqitjes së Dialogut Dinamik. Kështu që unë dua të di pozicionin dhe madhësinë e saktë të asaj kutie brenda kutisë së dialogut, por nuk mund t'i marr ato parametra.

Procedura në të cilën përdoret:

void CSerialCtrlDemoDlg::OnEventRead(char *inPacket,int inLength)
}
    int x=0;


    m_listboxRead.AddString(inPacket);      // display the incomming data in the 'Read' listbox

    CString str;                    // display the # of data's in 'Info'
    str.Format("%d bytes read",inLength);
    m_staticInfo.SetWindowText(str);

    CWnd *cWndSensor = GetDlgItem(IDC_SENSOR);  // show the fluctuation in the Picturebox 
    CDC *pDC = cWndSensor->GetDC();

    for (x = 0; x < 200; x++)
    {
        pDC->SetPixelV(x, 10, RGB(rand() % 255, 0, 0));
    }
}

X‹200 në ciklin for duhet të vendoset në gjerësinë e kutisë së fotografive.

Si mund t'i marr ato dimensione?

Shpresoj se ky është informacion i mjaftueshëm (?).

Përshëndetje, CJ.


Përgjigjet:


1

Kontrolli që më intereson është kutia e fotografive "IDC_SENSOR" (hyrja e fundit), e cila është përcaktuar në/si 41,62,256,76. Por në ekran këto përmasa janë të ndryshme, ndoshta për shkak të Paraqitjes Dialogu Dinamik.

Po, kjo është e saktë. Koordinatat në burimet e dialogut janë të specifikuara në DLU (njësi dialogu). Ju mund t'i konvertoni njësitë e dialogut në piksel duke thirrur funksionin MapDialogRect.

Por kjo nuk është në të vërtetë ajo që dëshironi të bëni këtu, sepse ju nuk dëshironi të kodoni fort koordinatat e dialogut në kodin tuaj. Nëse ndryshoni skedarin e burimit, dëshironi që kodi juaj të vazhdojë të funksionojë.

Unë dua të di pozicionin dhe madhësinë e saktë të asaj kutie brenda kutisë së dialogut

Ajo që ju duhet vërtet është të merrni koordinatat e kontrollit në ekran, në pixel. Ekzistojnë dy funksione të krijuara posaçërisht për këtë qëllim:

  • GetClientRect ju tregon drejtkëndëshin e dritares në koordinatat klient. Për një dritare fëmijësh, të tillë si një kontroll, këndi i sipërm majtas do të jetë gjithmonë (0, 0) dhe këndi i poshtëm djathtas do t'ju tregojë gjerësinë dhe lartësinë.
  • GetWindowRect ju tregon drejtkëndëshin e dritares në koordinatat ekran. Këto janë koordinata "absolute", në lidhje me ekranin virtual. Ndryshe nga drejtkëndëshi i klientit, drejtkëndëshi i dritares përfshin gjithashtu madhësinë e zonës jo-klient të dritares.

Ju ndoshta e dini tashmë këtë, por gjerësia e këtij drejtkëndëshi përcaktohet duke zbritur kufirin e majtë nga kufiri i djathtë. Në mënyrë të ngjashme, lartësia përcaktohet duke zbritur kufirin e sipërm nga kufiri i poshtëm. Ose, nëse përdorni klasën e mbështjellësit MFC, CRect (e cila është e këmbyeshme kudo me RECT, përfshirë kur thirrni dy funksionet e mësipërme), thjesht mund të telefononi funksionet anëtare Width dhe Height.

Sa i përket rastit tuaj të veçantë të përdorimit, duke qenë se po thërrisni GetDC në vetë dritaren e fëmijës, po merrni një klient DC dhe do t'ju duheshin koordinatat e klientit, kështu që do të telefononi GetClientRect. E thjeshtë. Përveç që kodi juaj është i gabuar. Po merrni një DC dhe po pikturoni jashtë një mbajtës mesazhi WM_PAINT, që do të thotë se çdo gjë që pikturoni mund të fshihet në intervale arbitrare. I gjithë vizatimi duhet të bëhet në përgjigje të një mesazhi WM_PAINT.

Një mënyrë e thjeshtë për ta arritur këtë në rastin tuaj do të ishte vendosja e stilit SS_OWNERDRAW për kontrollin tuaj IDC_SENSOR. Kjo vendos dialogun prind përgjegjës për vizatimin e përmbajtjes së kontrollit. Ai do të marrë WM_DRAWITEM mesazhe kur duhet të vizatohet kontrolli i fëmijëve. Shtoni një mbajtës OnDrawItem dhe bëni vizatimin tuaj atje. DRAWITEMSTRUCT i kaluar si parametër do t'ju tregojë drejtkëndëshin në të cilin duhet të vizatoni (rcItem).

Së fundi, duhet të vërej se SetPixelV është mjaft i ngadaltë. Nëse është mjaft e shpejtë për ju, thjesht injoroni pjesën tjetër të këtij komenti. Por nëse vizatimi në ekran është vërtet i ngadaltë, atëherë duhet të konsideroni krijimin dhe ruajtjen e një objekti bitmap. Tërhiquni në atë bitmap, duke vendosur pikselët e tij individualë dhe më pas thjesht hidhni atë bitmap në kontekstin e pajisjes së kontrollit tuaj. Qasja dhe manipulimi i pikselëve individualë të një bitmap jashtë ekranit është shumë më i shpejtë.

02.06.2016
  • Përshëndetje Cody, thanx për përgjigjen tuaj. E kam ndjesinë e saj, por tani më duhet ta marr në kodin tim. Kjo do të kërkojë disa eksperimente dhe eksplorime. Ka kohë që nuk kam programuar në Windows dhe ka nevojë për një mendim tjetër 'të tjerë'. - Përshëndetje, CJ. 03.06.2016

  • 2

    Kam arritur të marr detajet me GetClientRect:

    void CSerialCtrlDemoDlg::OnEventRead(char *inPacket,int inLength)
    
        {
            int i = 0;
            int j = 0;
            int x = 0;
            int y = 0;
            int w = 100;
            int h = 50;
    
            RECT sensorRect;
    
            CWnd *cWndSensor = GetDlgItem(IDC_SENSOR);
            CDC *pDC = cWndSensor->GetDC();
    
            cWndSensor->GetClientRect(&sensorRect);
    
            x = sensorRect.left;
            y = sensorRect.top;
            w = sensorRect.right - x;
            h = sensorRect.bottom - y;
    
    
            for (i = 0; i < w; i++)    // this fills the picturebox (for test only)
            {
                for (j = 0; j < h; j++)
                {
                    pDC->SetPixelV(i, j, RGB(rand() % 255, 0, 0));
                }
    
            }
        }
    

    Kështu që unë e shënoj këtë pyetje si përgjigje!

    Nuk jam i sigurt nëse kjo është mënyra 'e saktë', më mungon përvoja për këtë. Por funksionon, dhe atëherë duhet të jetë mjaft mirë :)

    Në vend që të vizatoj (drejtpërsëdrejti) në kutinë e fotografive, unë do të përdor një bitmap siç sugjerohet. Me të vërtetë është më mirë dhe më e lehtë për të punuar.

    Ajo që më duhet të zbuloj tani është se si ta përditësoj kutinë e dialogut në mënyrën e duhur me atë bitmap. Siç tha Cody, një vizatim i tillë nuk duhet të bëhet brenda kësaj rutine, por të trajtohet si një udhëzim i veçantë OnDrawItem. Hmm, më shumë për të mësuar.

    Thanx dhe përshëndetje, CJ

    06.06.2016
  • Gëzohem të shoh që e ke funksionuar këtë! Ky kod më duket i arsyeshëm. Stilistikisht, fraza ime do të ishte që ju nuk po shkruani C sipas specifikave të vitit 1990, kështu që ju duhet të preferoni të deklaroni variablat në pikën e tyre të inicializimit, në vend që të bëni një listë gjigante të variablave të inicializuara të paracaktuara në krye të funksionit. Me fjalë të tjera, deklaroni x, y, w dhe h pasi të keni marrë drejtkëndëshin e klientit, kur jeni duke caktuar vlerat aktuale. Por kjo nuk është një çështje korrektësie, vetëm një çështje stilistike. 07.06.2016
  • Sa i përket OnDrawItem, kjo është mënyra se si zotëroni-vizatoni një kontroll në MFC. Në të vërtetë, ka gjithmonë më shumë për të mësuar. Vizatimi i pronarit është një temë mjaft themelore në botën e programimit të Windows, por është ende një temë e avancuar. I dokumentuar mjaft rrallë në MSDN, por ka këtë hyrje. Jeni vetë për të përkthyer idiomat e papërpunuara Win32 në ato MFC. Nëse vendosni të gërmoni dhe keni vështirësi ta bëni atë, mund të bëni një pyetje të re në lidhje me të. 07.06.2016
  • Materiale të reja

    Masterclass Coroutines: Kapitulli-3: Anulimi i korutinave dhe trajtimi i përjashtimeve.
    Mirë se vini në udhëzuesin gjithëpërfshirës mbi Kotlin Coroutines! Në këtë seri artikujsh, unë do t'ju çoj në një udhëtim magjepsës, duke filluar nga bazat dhe gradualisht duke u thelluar në..

    Faketojeni derisa ta arrini me të dhënat false
    A e gjeni ndonjëherë veten duke ndërtuar një aplikacion të ri dhe keni nevojë për të dhëna testimi që duken dhe duken më realiste ose një grup i madh të dhënash për performancën e ngarkesës...

    Si të përdorni kërkesën API në Python
    Kërkesë API në GitHub për të marrë depot e përdoruesve duke përdorur Python. Në këtë artikull, unë shpjegoj procesin hap pas hapi për të trajtuar një kërkesë API për të marrë të dhëna nga..

    Një udhëzues hap pas hapi për të zotëruar React
    Në këtë artikull, do të mësoni se si të krijoni aplikacionin React, do të mësoni se si funksionon React dhe konceptet thelbësore që duhet të dini për të ndërtuar aplikacione React. Learning..

    AI dhe Psikologjia — Pjesa 2
    Në pjesën 2 të serisë sonë të AI dhe Psikologji ne diskutojmë se si makineritë mbledhin dhe përpunojnë të dhëna për të mësuar emocione dhe ndjenja të ndryshme në mendjen e njeriut, duke ndihmuar..

    Esencialet e punës ditore të kodit tim VS
    Shtesat e mia të preferuara - Git Graph 💹 Kjo shtesë është vërtet e mahnitshme, e përdor përpara se të filloj të punoj për të kontrolluar dy herë ndryshimet dhe degët më të fundit, mund të..

    Pse Python? Zbulimi i fuqisë së gjithanshme të një gjiganti programues
    Në peizazhin gjithnjë në zhvillim të gjuhëve të programimit, Python është shfaqur si një forcë dominuese. Rritja e tij meteorike nuk është rastësi. Joshja e Python qëndron në thjeshtësinë,..