COMPINFO - კომპიუტერული ინფორმაცია - სტატიები » პროგრამირება » რომელი ჯობია: სილამაზე თუ სისადავე?

http://compinfo.ge/index.php/index.php?type=preview&area=1&p=articles&id=13


ადგილმდებარეობა  მთავარი » სტატიები » პროგრამირება
რომელი ჯობია: სილამაზე თუ სისადავე?

    სანამ საქმეს შევუდგებოდეთ ცოტათი წაფილოსოფოსება მოგვიწევს;
    დავიწყოთ იქიდან რომ CompInfo მე-15 ნომერში როცა ვლაპარაკობდით C++-ის ისტორიაზე, რამდენიმეჯერ შევეხეთ ზოგადად პროგრამირების ენის ორიენტაციის ფენომენს, ანუ ენის მიერ კონკრეტული ამოცანების გადაწყვეტისადმი ორიენტირებულობას.
    მაშ, რაშია ახლა საქმე. . .
    ვინც ჩახედულია ამ საქმეში და გადაუხედავს რამდენიმე უცხოური ვებ-ფორუმებისათვის, კარგად იცი თუ რას წარმოადგენს ფიქრი იმაზე, თუ რომელი პროგრამირების ენა ანუ თანამედროვე ტერმინოლოგიას თუ ვიხმართ, რომელი IDE(დეველოფმენთის ინტეგრირებული გარემო)  აირჩიო თავიდანვე შემდგომი სწავლისა თუ მუშაობისათვის, რადგან ეს არ არის 80-იანი წლები, როცა ენის სასწავლებლად საკმარისი იყო ერთი 100 გვერდიანი წიგნუკა და რამდენიმე 10-ული ოპერატორის თუ ფუნქციის დამახსოვრება.
    მაგალითად, ეს ჩვენი ლეგენდარული Delphi ფაქტიურად უკვე გადაიქცა უცხო ენად რომელშიც არის ფუქციებისა და კომპონენტთა სახელების უკიდეგანო ოკეანე.
თუმცა, ძალიან შორს რომ არ წავიდეთ, ამ საკითხიდან გამოვყოფ ერთ ქვესაკითხს, რომელიც ჩვენთვის უფრო მნიშვნელოვანია ამ კონკრეტულ შემთხვევაში;

- რა არის Dephi-ს დევიზი?
- მარტივად, სწრაფად და ხარისხიანად!
- რა იძლევა მასში ერთდროულად ამ სამი პირობის შესრულების საშუალებას?
-  Visual კომპონენტთა სიმრავლე (VCL).

    მაშინ, რა არის პროგრამის ხარისხიანობა? იგულისხმება თუ არა მასში სხვა ყველაფერთან ერთად თუნდაც იგივე გარე ინტერფეისის სილამაზე და მრავალფეროვნება? რა თქმა უნდა იგულისხმება და ყველაფერ ამის საშუალებას იძლევა მაგალითად იგივე Delphi.  

    მოდით ახლა საკითხს ცოტა სხვაგვარად მივუდგეთ;
როდესაც პროგრამისტი, მუშაობ ცოტათი სერიოზულ ალგორითმულად გადატვირთულ, მაგალითად, სამეცნიერო, მოდელირების ან თუნდაც ქსელური პროგრამირების ტიპის პროექტზე, მაშინ ვიზუალური კომპონენტების გაფერადების, გალამაზების, ხატვისა არა თუ დრო არ გრჩება არამედ სურვილიც კი არა გაქვს ამისი, ხელშემშლელ მომენტებზე რომ არაფერი ვთქვათ. იგივე ეხება ამ პროგრამის მომხმარებელსაც.

    ნუ, არ ვიცი იყო თუ არა ეს არგუმენტი თუნდაც იმ მიზეზებიდან ერთ-ერთი მიზეზთაგანი რომლის გამოც ისეთმა გიგანტ-გომპანიამ როგორიც Microsoft-ია VisualC++-ის IDE –ში არ ჩასვა კომპონენტებზე ფერების დაყენების WYSIWYG ტექნოლოგია (WYSIWYG  - What You See Is What You Get), მაგრამ ყოველ შემთხვევაში მე ამ მომენტის ასეთმა ახსნამ პრინციპში დამაკმაყოფილა.
    მაგრამ, გამორიცხული არაფერის არ არის და შესაბამისად ყოველთვის არსებობს პროგრამის გალამაზების საჭიროებაც.
    მოკლედ, უნდა გადაწყდეს “პრობლემა”:  როგორ გავაფერადოთ Visual C++-ში Edit Box, Static Text, ტექსტის, ტექსტის ფონიდა ა.შ.

    მიხვდით რომ საქმე გვაქვს Windows-ის აპლიკაციის გარე ინტერფეისის “მაკიაჟთან”.
    მაშ, შევუდგეთ საქმეს.
    იგულისხმება რომ მკითხველს აქვს VC++-ის გარემოში Wizard-თან მუშაობის, დიალოგური ფანჯრის შექმნის და მასზე კომპონენტების განლაგების ელემენტარული გამოცდილება.
    ჩემი იარაღია VC++ 7.0. (ქვემოთ მოყვანილი კოდი სამართლიანია ასევე VC++ 6.0-თვისაც.) შევქმნათ ახალი პროექტი TestColor, დილოგური ფანჯრის სახით, არ გვინდა არც ActiveX-ებიდა არც About Box:

Image at http://www.g3b.ge

    სურათიდან ჩანს, რომ ფორმაზე განლაგებულია 2 ახალი კომპონენტი Edit Box(“Sample edit box”) და Button(“Test”), ასევე გამოვიყენებთ Static Box-საც რომელსაც სვამს თვითონ Wizard-.

    ჯერ შემოვიღოთ ასეთი აღწერები  TestColorDlg.h  ფაილში:

#define   CONTROL_MAX_COUNT  10
 
enum     _window_items
{
  Ground     =1,
  TextGround =2, 
  Text       =3
};
 
typedef  _window_items   WINITEMS;

    ჩამოთვლაში _window_items მოყვანილია ვინდოუს-კონტროლის სამი ძირითადი ელემენტი: ფონი, ტექსტის ფონი და ტექსტი. შემდეგში ჩვენ შევცვლით სწორედ ამ ელემენტების ფერს. (მე მაქვს ასეთი შეთანხმება რომ ჩამოთვლაში ელემენტის ნომერს ვიწყებ არა 0-დან არამედ 1-დან).
    აღვწეროთ შემდეგი მასივები   და ფუნქციები CTestColorDlg კლასში (ცვლილებები მოცემულია მუქი ლურჯი ფერით):

 typedef  _window_items   WINITEMS;

class CTestColorDlg : public CDialog

{

// Construction

      COLORREF   bkColor[CONTROL_MAX_COUNT];

      COLORREF   txtColor[CONTROL_MAX_COUNT];

      CBrush     Brush[CONTROL_MAX_COUNT];

public:

      void  SetWindowColor(int _ID, WINITEMS _item, COLORREF _color);

    void SetWindowColor(int _ID, COLORREF _Ground, COLORREF _TextGround,COLORREF _Text);

. . . . . .

protected:

    virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV support

    afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) ;

    . . . . . . .  .

    და გავაკეთოთ ამ ფუნქციების შესაბამისი რეალიზაციები TestColorDlg.cpp ფაილში:

HBRUSH CTestColorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

  return hbr;

}

void  CTestColorDlg::SetWindowColor(int _ID, WINITEMS _item, COLORREF _color)

{

}

void  CTestColorDlg::SetWindowColor(int _ID, COLORREF _Ground, COLORREF _TextGround,COLORREF _Text)

{

}

    ყოველ შემთხვევაში დააკომპილეთ პროგრამა და გაუშვით, რათა დარწმუნდეთ, რომ ყველაფერი სწორედ არის.
    როგორც ხვდებით ხდება SetWindowColor ფუნქციის გადატვირთვა, შემდეგში დავრწმუნდებით, რომ ეს სრუალიად სამართლიანია და აკმაყოფილებს ოოპ(ობიექტ-ორიენტირებული პროგრამირება)-ის პრინციპებს.
    ეს ფუნქცია გამოიყენება კონტროლის ფერის შესაცვლელად გადაეცემა რა მას შესაბამისი პარამეტრები.
ხოლო, რაც შეეხება ფუნქციას  OnCtlColor  იგი არის დიალოგური კლასის სტანდარტული ფუნქცია და გამოიძახება ყოველთვის როცა ხდება ფანჯრისა და მისი ელემენტების აღდგენა(გამოხატვა) ეკრანზე, ეს იქნება პროგრამის გაშვება, ერთი ფანჯრიდან მეორეზე გადასვლა თუ უბრალოდ Move - ფანჯრის სისტემური ოპერაცია. სანამ თვითოეული ამ ფუნქციის ტანის  განხილვას შევუდგებოდეთ, ჩვენს პროგრამას კიდევ უნდა დავამატოთ ერთი დეტალი, რომლის გარეშეც კომპილატორი შეცდომას არ გამოგვიგდებს, მაგრამ არც იმას გააკეთებს რაც გვინდა (სხვათაშორის ეს უკანასკნელი მომენტი ხშირად მხვდება MSVC-სთან პრაქტიკაში).
    იმედია მკითხველისთვის ცნობილია თუ რას წარმოადგენს მაკროსთა შემდეგი სისტემა

 BEGIN_MESSAGE_MAP(CTestColorDlg, CDialog)

      . . . . . . .

      ON_WM_PAINT()

      ON_WM_QUERYDRAGICON()

      . . . . . . . .

      //}}AFX_MSG_MAP

END_MESSAGE_MAP()

და რა საპასუხისმგებლო მოვალეობა აკისრია მას პროგრამის მუშაობის პროცესში. სწორედ აქ უნდა დავამატოთ რეაქცია ფერების გამოსახვის პროცედურის შესასრულებლად:

 BEGIN_MESSAGE_MAP(CTestColorDlg, CDialog)

      . . . . . . .

      ON_WM_PAINT()

      ON_WM_QUERYDRAGICON()

     ON_WM_CTLCOLOR( ) 

      . . . . . . . .

      //}}AFX_MSG_MAP

END_MESSAGE_MAP()

   ესეც ასე.

   ახლა შევცვალოთ შესაბამისი OnCtlColor ფუნქციის ტანი შემდეგნაირად:

 HBRUSH CTestColorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

 HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

  if ( pWnd->GetDlgCtrlID() == IDC_STATIC1)

 {

         pDC->SetBkColor(bkColor[0]);

         pDC->SetTextColor(txtColor[0]);

         return (HBRUSH)Brush[0].GetSafeHandle();

 }  

 if ( pWnd->GetDlgCtrlID() == IDC_EDIT1 )

 {

         pDC->SetBkColor(bkColor[1]);

         pDC->SetTextColor(txtColor[1]);

         return (HBRUSH)Brush[1].GetSafeHandle();

 }     

  return hbr;

}

    ხოლო 3 პარამეტრიანი SetWindowColor ფუნქციის ტანი კი ასე –

 void  CTestColorDlg::SetWindowColor(int _ID, WINITEMS _item, COLORREF _color)

{

   if(_ID==IDC_STATIC1)

   {

       if(_item==Ground)

      {

          Brush[0].DeleteObject();Brush[0].CreateSolidBrush(_color);

      }

       if(_item== TextGround)bkColor[0]=_color;

       if(_item==Text)txtColor[0]=_color;

    }

    if(_ID==IDC_EDIT1)

    {

         if(_item==Ground)

         {

          Brush[1].DeleteObject();Brush[1].CreateSolidBrush(_color);

         }

               if(_item== TextGround)bkColor[1]=_color;

         if(_item==Text)txtColor[1]=_color;

     }

    GetDlgItem(_ID)->ShowWindow(SW_HIDE);

    GetDlgItem(_ID)->ShowWindow(SW_RESTORE);

}

და ბოლოს იგივე, ოღონდ გადატვირთული ფუნქცია:

void  CTestColorDlg::SetWindowColor(int _ID, COLORREF _Ground, COLORREF _TextGround,COLORREF _Text)

{

     SetWindowColor(_ID,Ground,_Ground);   

    SetWindowColor(_ID,TextGround,_TextGround);        

    SetWindowColor(_ID,Text,_Text);           

}

    ეს უკანასკნელი ფუნქცია შეგვიძლია გამოვიყენოთ უკვე უშუალოდ კონკრეტული კონტროლის ფერის, ტექსტის ფონის ფერის და ტექსტის ფერის დასაყენებლად. პირველი პარამეტრი არის იმ კონტროლის ID, რომლის ფერებსაც ვცვლით, მეორე არის ფონის ფერი, მესამე ტექსტის ფონის ფერი,  ხოლო მეოთხე კი თვით ტექსტის ფერი.
პრინციპში პროგრამა უკვე სრულყოფილად მუშაობს, მაგრამ პუნქტუალურობა და სადღაც საჭიროებაც მოითხოვს რომ დიალოგური ფანჯრის ინიციალიზაციის მეთოდშივე მოვახდინოთ საწყისი ფერების დაყენება:

 BOOL CTestColorDlg::OnInitDialog()

{

      CDialog::OnInitDialog();

       // Set the icon for this dialog.  The framework does this automatically

      //  when the application's main window is not a dialog

      SetIcon(m_hIcon, TRUE);             // Set big icon

      SetIcon(m_hIcon, FALSE);            // Set small icon

       // TODO: Add extra initialization here

      SetWindowColor(IDC_EDIT1,RGB(255,0,0),RGB(255,0,0),RGB(0,0,255));

     SetWindowColor(IDC_STATIC1,RGB(255,255,0),RGB(255,255,0),RGB(0,150,0));

       return TRUE;  // return TRUE  unless you set the focus to a control

}

    გავიხსენოთ რომ იდენტიფიკატორი IDC_STATIC1 თავისით არ ენიჭება  Static  კონტროლს და ამიტომ იგი ჩვენით უნდა შევცვალოთ მის Property-ებში.

    მიაკომპილეთ, გაუშვით და . . .

Image at : www.g3b.ge

 

    ესეც შენი ფერადი ინტერფეისი. ყოველ შემთხვევაში ჩემთან ასეა.
    ახლა შეგვიძლია გავხდეთ ცოტათი უფრო მეტად ამბიციურები და მოვახდინოთ ფერის შეცვლა ”Use-Time” პროცესში.
    დავაჭიროთ ორჯერ Test კლავიშს და შეიქმნება ვინდოუსის ამ მესიჯის დამმუშავებელი მეთოდი.

    შევცვალოთ იგი ასე:

void CTestColorDlg::OnBnClickedButton1()

{

      // TODO: Add your control notification handler code here

       SetWindowColor(IDC_STATIC1, RGB(0,255,0), RGB(0,255,0), RGB(0,0,255));

}

    გავუშვათ პროგრამა, დავაწკაპუნოთ Test კლავიშზე და ვნახავთ, რომ Static კონტროლის ფონის ფერი შეიცვლება მწვანეთი. იგივე შეგვიძლია გავაკეთოთ ფანჯრის სხვა კონტროლებზედაც.
    ცხადია ეს არ არის ჩვენი მიზნის მიღწევის ერთად-ერთი გზა და მსგავსის გაკეთება შეიძლება სხვანაირადაც, თუმცა ნაკლებად სავარაუდოა, რომ რაიმე პრინციპული განსხვავება შეგვხვდეს სადმე. საერთოდ, კი MFC-ეს ერთ-ერთი გრაფიკული დანიშნულების კლასი CDC  ამ მხრივ დიდ შესაძლებლობებს იძლევა. ალბათ შენიშნავდით, რომ OnCtlColor ფუნქციის ერთ-ერთი პარამეტრი წარმოადგენს ამ კლასზე მაჩვენებელს და მას საკმაოდ მნიშვნელოვანი ფუნქცია აკისრია.

 აი, სულ ეს იყო.

რეზიუმე

დავაყენე ფანჯრის ფერი,
ეს სულაც არ იყო ძნელი,
არსად არ დამჭირდა “ჰელფი”,
დამეწიოს ახლა დელფი.

  

 ავტორი:  გიორგი ბაწაშვილი(G3B)

  
ინფორმაცია


თემატური სტატიები




ბმულები შესაბამის თემაზე




გამოხმაურება

აღდგენილია სტატიის საწყისი ვარიანტი
07-02-2010, 11:14:19 | G3B

დავაყენე ფანჯრის ფერი,
ეს სულაც არ იყო ძნელი,
არსად არ დამჭირდა “ჰელფი”,
დამეწიოს ახლა დელფი.

21-05-2009, 02:25:51 | GioDorcel


კომენტარის დატოვება
თქვენ არ შეგიძლიათ კომენტარების დატოვება.