Color picker

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
Post Reply
carrera
Junior
Junior
Posts: 38
Joined: 23 Aug 2007, 12:06

Color picker

Post by carrera » 18 Feb 2013, 10:23

Salut.

- As avea o intrebare: vreau sa fac un color-picker ca cel din imaginea atasata (e luat de la photoshop) si nu prea am idee cum e facut.Initial am vrut sa-l fac dintr-un listcontrol (in care sa folosesc small-icons) dar din cauza spatiului pe care-l lasa intre icon-uri (deci intre culori) nu e o solutie.Alta solutie ar fi sa desenez manual culorile, iar culoarea selectata s-o aflu in functie de coordonatele "click-ului" dar pare prea migalos... exista vreo solutie de mijloc?

Multumesc.

1.jpg
1.jpg (18.41 KiB) Viewed 13085 times



User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 18 Feb 2013, 16:18

Versiunea clasica si cea mai usoara este sa folosesti dialogul de selectie culoare gata preparat in Windows.
Pentru aceasta ai in Windows API functia ChooseColor iar in MFC clasa CColorDialog.
Common Color Dialog Box.jpg
Common Color Dialog Box.jpg (31.44 KiB) Viewed 13077 times
Eu zic ca, in general e suficenta si mai mult decat satisfacatoare.

Alternativ, MFC Feature Pack, inclus in Visual Studio 2008 SP1 si in versiunile mai noi, contine clasa CMFCColorDialog care arata ceva mai fancy si pune mai multe culori pe fatzau.
Feature Pack Color Dialog.jpg
Feature Pack Color Dialog.jpg (21.48 KiB) Viewed 13077 times
Tu alegi.

Vezi si:

carrera
Junior
Junior
Posts: 38
Joined: 23 Aug 2007, 12:06

Re: Color picker

Post by carrera » 18 Feb 2013, 21:59

Merci de ajutor Ovidiu, picker-ele astea sint cam mari, vreau un picker extrem de restrins, care sa stea in permanenta la vedere, exact ca in photoshop.Pina la urma o sa le fac de mina, chiar daca e putin efort.Merci again.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 19 Feb 2013, 12:21

Ce-si face omu cu mana lui, se cheama "lucru manual". :D

In fine, sa zicem, astea-s cerintele si trebuie sa te abati de la "standard".
Amandoua metodele pe care le-ai enumerate la inceput sunt fezabile.
1. Faci un listview control (CListCtrl) custom sau owner-draw; in cazul acesta cred ca mai porivita e o lista report style si nu small icon.
2. Faci un control custom sau ActiveX, in care desenezi tu cu mana ta un grid colorat.

Depinde cum ti se pare mai usor: sa macelaresti un control deja existent sau sa faci altul de la zero.

Viorel
Microsoft MVP
Microsoft MVP
Posts: 293
Joined: 13 Jul 2007, 12:26

Re: Color picker

Post by Viorel » 19 Feb 2013, 12:34

Încearcă și ultimul MFC care include controlul CMFCColorPickerCtrl: http://msdn.microsoft.com/en-us/library/bb984075.aspx.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 19 Feb 2013, 14:28

L-am incercat eu acum si "crapa" din toate incheieturile. :)
In fine, asta o putem rezolva (are nevoie de oaresce initializari) insa se pare ca CMFCColorPickerCtrl a fost facut special ca sa fie folosit de CMFCColorDialog deci nu ne apropiem prea mult de look 'n feel-ul pe care-l vrea carrera.
Asta la prima vedere, poate ma insel...

carrera
Junior
Junior
Posts: 38
Joined: 23 Aug 2007, 12:06

Re: Color picker

Post by carrera » 19 Feb 2013, 14:56

Ovidiu Cucu wrote:
1. Faci un listview control (CListCtrl) custom sau owner-draw; in cazul acesta cred ca mai porivita e o lista report style si nu small icon

Buna idee, ramane doar sa colorez celulele.Chiar daca nu exista vreo functie standard de colorare, ramane totusi cea mai simpla solutie.
thx.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 19 Feb 2013, 15:12

carrera wrote: [...] ramane doar sa colorez celulele.Chiar daca nu exista vreo functie standard de colorare, ramane totusi cea mai simpla solutie.
Nu chiar. Un control listview nu are "celule". Revin mai tarziu cu un draft si cu ceva explicatii suplimentare.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 22 Feb 2013, 11:29

Promisesem un draft si niste explicatii... :)
Un listview control nu este organizat ca un "grid" desi seamana cu un grid daca are report style (LVS_REPORT).
Este doar o colectie de item-uri, fiecare item putand avea asociat un numar de subitem-uri. Daca un item poate contine informatii suplimentare, nu acelasi lucru se poate zice si pentru pentru subitem-uri.
De aceea n-o sa gasesti pentru el metode gen "SetCellColor", ca in cazul unui grid.

Spuneam totusi ca s-ar putea "carpi" un color picker custom (za zicem, similar cu cel din Photosop) cu un listview custom-draw sau owner-draw.
Vezi mai intai ce inseamna fiecare aici: Deci...
  1. Folosind un listview custom-draw
    Color Picker Listview (custom-draw).jpg
    Color Picker Listview (custom-draw).jpg (15.34 KiB) Viewed 12992 times
    Color Picker Listview (custom-draw).zip
    (25.26 KiB) Downloaded 468 times
    In principiu, este super-easy. Nu avem decat sa tratam NM_CUSTOMDRAW trimis via WM_NOTIFY.
    In faza "subitem pre-paint" (NM_CUSTOMDRAW vine cu NMLVCUSTOMDRAW::nmcd::dwDrawStage avand valoarea CDDS_ITEMPREPAINT | CDDS_SUBITEM), ii spunem sitemului cu ce culoare sa picteze subitem-ul respectiv si am rezolvat problema.
    Ceva de genul

    Code: Select all

    void CColorListCtrl::_HandleSubitemPrePaint(LPNMLVCUSTOMDRAW pNMCD, LRESULT *pResult)
    {
       // Note: for a listview, nmcd.dwItemSpec keeps the item index 
       const int nItem = (int)pNMCD->nmcd.dwItemSpec;
       const int nSubItem = pNMCD->iSubItem;
       const int nColor = nItem * m_nColCount + nSubItem;
       if(nColor < m_arrColors.GetSize())
       {
          pNMCD->clrTextBk = m_arrColors[nColor]; // m_arrColors is an array of colors
       }
       // ...
    }

    Dezavantajul e ca nu putem modifica dimensiunea unui item. In caz ca se doreste asta, atunci vrand-nevrand trebie facuta o lista owner-draw.
  2. Folosind un listview owner-draw
    Color Picker Listview (owner-draw).jpg
    Color Picker Listview (owner-draw).jpg (6.76 KiB) Viewed 12992 times
    Color Picker Listview (owner-draw).zip
    (25.25 KiB) Downloaded 440 times
    In primul rand, pentru a o fi owner-draw lista trebuie sa aiba stilul LVS_OWNERDRAWFIXED (proprietatea "Owner Draw Fixed" trebuie setata pe "True" in editorul de resurse).
    In continuare putem trata mesajele WM_MEASUREITEM si WM_DRAWITEM pentru a fixa dimensiunea unui item si repectiv pentru a desena itemul asa cum vrea muschii nostri.
    Pentru a trata WM_DRAWITEM putem suprascrie folosind vizard-ul functia DrawItem.
    WM_MEASUREITEM trebuie mapat "la mana".
    Ca si dezavantaj fata de metoda precedenta este faptul ca WM_DRAWITEM este trimis pentru fiecare item, nu si pentru fiecare subitem in parte, asa ca avem de facut oaresce mici calcule in plus.
    Mai multe amanunte de implemetare gasesti in demo-ul atasat.
Aplicatiile demo sunt doar draft. Daca vrei sa folosesti unul sau altul, va trebui sa le dezvolti adaugand metodele necesare, de exemplu o metoda pentru incarcat o anume paleta de culori.

In fine, toate bune si frumoase... am dat exemplele de mai sus doar pentru a demonstra cum se poate face rapid un color picker folosind un listview control.
Daca ar fi sa aleg, eu as alege:
  1. color picker-ul deja facut in Windows/MFC, iar daca nu...
  2. as face un control (custom sau ActiveX) de la zero.

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Color picker

Post by mesajflaviu » 22 Feb 2013, 16:41

Iau de aici fiecare proiect sa-l incerc, si daca nu e proiect VC6, no pb, il convertesc eu in VC6 ... insa nu pot face asta daca fisierul proiect contine spatiu ... de altadata, nu acum, puteti pune in loc de spatiu ceva caracter ? Nu conteaza ce, numa spatiu sa nu fie, pentru cei care traiesc in preistorie .... :D

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 22 Feb 2013, 17:04

[off-topic]
Imi pare rau, insa in momentul asta XP-ul meu (pe care am VS6.0) e vraiste si din moment ce m-am obisnuit cu Windows 7, ma trage din ce in ce mai greu ata sa-l reinstalez. O sa-l reinstalez totusi pentru ca mai fac din cand in cand teste pe XP, insa nu stiu cand.
Oricum, in afara de cazul in care un proiect contine cine sitie ce chestii noi care nu-s in MFC-ul si SDK-ul din VS6, "portarea" n-ar fi o asa mare problema.
Fa-ti un proiect nou (in cazul de fata, un proiect dialog-based numit "Demo") si-apoi pur si simplu copie fisierele sursa in el. Mai sunt de rezolvat cateva mici incompatibilitati, in rest nu cred ca-s mari probleme.
De exemplu chestia asta pusa de wizard-ul din VS200x

Code: Select all

   ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CColorListCtrl::OnNMCustomdraw)
o sa-ti dea eroare in VS6. Nu trebuie decat sa stergi "&CColorListCtrl::".

Of course, o sa incerc de-acum si sa nu mai pun spatii in numele solutiei. :)

carrera
Junior
Junior
Posts: 38
Joined: 23 Aug 2007, 12:06

Re: Color picker

Post by carrera » 25 Feb 2013, 15:03

Merci fain Ovidiu.
As mai avea o intrebare: ar fi vreo metoda de-a micsora dimensiunea item-ilor, adica as putea sa fac mai mici patratelele colorate?

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 26 Feb 2013, 15:10

Daca vrei, poti (in varianta owner-draw). :)
Arunci mai intai o privire in handlerul lui WM_MEASUREITEM, (MeasureItem)

Code: Select all

void CColorListCtrl::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
   lpMIS->itemHeight = m_nColorItemHeight;
   lpMIS->itemWidth = m_nColorItemWidth * m_nColCount;
}
unde se vede clar ca se poate.

Eventual, te uiti si la articolul asta Color Picker Listview Control.

carrera
Junior
Junior
Posts: 38
Joined: 23 Aug 2007, 12:06

Re: Color picker

Post by carrera » 27 Feb 2013, 15:44

Super.Tre' sa vin cu o sticla de vin cind mai ajung prin Iasi :D
Merci!

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Color picker

Post by Ovidiu Cucu » 03 Mar 2013, 10:12

Poate ca, pana vii tu in Iasi, fac un control color picker de la zero (custom sau ActiveX).
Insa ala nu costa o stica ci un butoi cu vin. :)

Post Reply