Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Clickable Bitmap UI question

Clickable Bitmap UI question

Scheduled Pinned Locked Moved C / C++ / MFC
questiongraphicsdesignhelp
11 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    b_girl
    wrote on last edited by
    #1

    In the interface I'm creating I have a dialog box that opens up containing a bitmap. Something different will happen depending on where on the bitmap the user clicks. I have 2 bitmaps, the "real" and the "template". I don't know why, but when the user clicks on the bitmap, the colour values are being read from the real bitmap and not the template one. I think the problem comes from this bit of code, but I'm not completely sure why: in my constructor: ... HBITMAP hTemplateBMP; hTemplateBMP = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PERIODIC_TMPL)); ... in my on clicked message handler: POINT pt; CDC *pDC = NULL; CDC memDC; HBITMAP hOldBMP = NULL; COLORREF crColourAtPoint = 0; GetCursorPos(&pt); m_periodicBitmap.ScreenToClient(&pt); pDC = m_periodicBitmap.GetDC(); memDC.CreateCompatibleDC(pDC); hOldBMP = (HBITMAP)memDC.SelectObject(hTemplateBMP); crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y); ... IDB_PERIODIC_TMPL is the template for my bitmap... I believe crColourAtPoint ends up being the colour of the point in the real bitmap, not the template bitmap. Why??

    J T 2 Replies Last reply
    0
    • B b_girl

      In the interface I'm creating I have a dialog box that opens up containing a bitmap. Something different will happen depending on where on the bitmap the user clicks. I have 2 bitmaps, the "real" and the "template". I don't know why, but when the user clicks on the bitmap, the colour values are being read from the real bitmap and not the template one. I think the problem comes from this bit of code, but I'm not completely sure why: in my constructor: ... HBITMAP hTemplateBMP; hTemplateBMP = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PERIODIC_TMPL)); ... in my on clicked message handler: POINT pt; CDC *pDC = NULL; CDC memDC; HBITMAP hOldBMP = NULL; COLORREF crColourAtPoint = 0; GetCursorPos(&pt); m_periodicBitmap.ScreenToClient(&pt); pDC = m_periodicBitmap.GetDC(); memDC.CreateCompatibleDC(pDC); hOldBMP = (HBITMAP)memDC.SelectObject(hTemplateBMP); crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y); ... IDB_PERIODIC_TMPL is the template for my bitmap... I believe crColourAtPoint ends up being the colour of the point in the real bitmap, not the template bitmap. Why??

      J Offline
      J Offline
      Jason Henderson
      wrote on last edited by
      #2

      For one thing, you are mixing MFC with Win32 GDI and that tends to get confusing. Instead of using HBITMAP, use a CBitmap and the code should look like this:

      in my constructor:
      ...
      CBitmap TemplateBMP;
      TemplateBMP.LoadBitmap(IDB_PERIODIC_TMPL);
      ...

      in my on clicked message handler:
      POINT pt;
      CDC *pDC = NULL;
      CDC memDC;
      CBitmap OldBMP = NULL;
      COLORREF crColourAtPoint = 0;

      GetCursorPos(&pt);
      m_periodicBitmap.ScreenToClient(&pt);
      pDC = m_periodicBitmap.GetDC();
      memDC.CreateCompatibleDC(pDC);
      OldBMP = (CBitmap*)memDC.SelectObject(&TemplateBMP);
      crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y);
      ...

      "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

      Jason Henderson
      blog | articles

      B 1 Reply Last reply
      0
      • J Jason Henderson

        For one thing, you are mixing MFC with Win32 GDI and that tends to get confusing. Instead of using HBITMAP, use a CBitmap and the code should look like this:

        in my constructor:
        ...
        CBitmap TemplateBMP;
        TemplateBMP.LoadBitmap(IDB_PERIODIC_TMPL);
        ...

        in my on clicked message handler:
        POINT pt;
        CDC *pDC = NULL;
        CDC memDC;
        CBitmap OldBMP = NULL;
        COLORREF crColourAtPoint = 0;

        GetCursorPos(&pt);
        m_periodicBitmap.ScreenToClient(&pt);
        pDC = m_periodicBitmap.GetDC();
        memDC.CreateCompatibleDC(pDC);
        OldBMP = (CBitmap*)memDC.SelectObject(&TemplateBMP);
        crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y);
        ...

        "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

        Jason Henderson
        blog | articles

        B Offline
        B Offline
        b_girl
        wrote on last edited by
        #3

        Thanks. That didn't really change anything though. I was using those files you sent me before as a reference. You know how you made those periodic table bitmaps? I was just reading in the colours that you had in that exel file you sent along with the bitmaps, should I go through and re-do the template bitmap along with the colour values in that excel file in order to make it set up as r, g, b not just a single colour value? I put this in thinking it would work, but maybe that's where my problem is actually coming from: //get the colour value from the string read in from the file cstrInfo = breakString(cstrLine, &strPos); int intColour = atoi(cstrInfo); r = GetRValue(intColour); g = GetGValue(intColour); b = GetBValue(intColour); //SetColour takes COLORREF as it's parameter BmpItem.SetColour(RGB(r,g,b)); the value of crColourAtPoint is always soo much more than the value returned by the GetColour function (which is COLORREF)

        J 1 Reply Last reply
        0
        • B b_girl

          Thanks. That didn't really change anything though. I was using those files you sent me before as a reference. You know how you made those periodic table bitmaps? I was just reading in the colours that you had in that exel file you sent along with the bitmaps, should I go through and re-do the template bitmap along with the colour values in that excel file in order to make it set up as r, g, b not just a single colour value? I put this in thinking it would work, but maybe that's where my problem is actually coming from: //get the colour value from the string read in from the file cstrInfo = breakString(cstrLine, &strPos); int intColour = atoi(cstrInfo); r = GetRValue(intColour); g = GetGValue(intColour); b = GetBValue(intColour); //SetColour takes COLORREF as it's parameter BmpItem.SetColour(RGB(r,g,b)); the value of crColourAtPoint is always soo much more than the value returned by the GetColour function (which is COLORREF)

          J Offline
          J Offline
          Jason Henderson
          wrote on last edited by
          #4

          The csv file I sent you uses just a COLORREF rather than the RGB components. BmpItem.SetColour(atol(cstrInfo));

          "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

          Jason Henderson
          blog | articles

          B 1 Reply Last reply
          0
          • J Jason Henderson

            The csv file I sent you uses just a COLORREF rather than the RGB components. BmpItem.SetColour(atol(cstrInfo));

            "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

            Jason Henderson
            blog | articles

            B Offline
            B Offline
            b_girl
            wrote on last edited by
            #5

            OOOHHHH!!! I wasn't too sure what a COLORREF was. is this: CBitmap *OldBMP; OldBMP = memDC.SelectObject(&TemplateBMP); the same as: CBitmap OldBMP; OldBMP = (CBitmap*)memDC.SelectedObject(&TemplateBMP); memDC.SelectedObject(&TemplateBMP) returns a CBitmap*....

            J 1 Reply Last reply
            0
            • B b_girl

              OOOHHHH!!! I wasn't too sure what a COLORREF was. is this: CBitmap *OldBMP; OldBMP = memDC.SelectObject(&TemplateBMP); the same as: CBitmap OldBMP; OldBMP = (CBitmap*)memDC.SelectedObject(&TemplateBMP); memDC.SelectedObject(&TemplateBMP) returns a CBitmap*....

              J Offline
              J Offline
              Jason Henderson
              wrote on last edited by
              #6

              No, its not the same. OldBMP in the second example is a CBitmap, not a CBitmap pointer. SelectObject returns a CBitmap pointer, so you don't have to cast it. That was a mistake.

              "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

              Jason Henderson
              blog | articles

              B 1 Reply Last reply
              0
              • J Jason Henderson

                No, its not the same. OldBMP in the second example is a CBitmap, not a CBitmap pointer. SelectObject returns a CBitmap pointer, so you don't have to cast it. That was a mistake.

                "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

                Jason Henderson
                blog | articles

                B Offline
                B Offline
                b_girl
                wrote on last edited by
                #7

                I'm doing something seriously wrong. No matter where I click on the bitmap, crColourAtPoint is ALWAYS set at 16777215. I don't understand why. CBitmap TemplateBMP; ... TemplateBMP.LoadBitmap(IDB_PERIODIC_TMPL); ... POINT pt; CDC *pDC = NULL; CDC memDC; COLORREF crColourAtPoint = 0; CBitmap *hOldBMP = NULL; //obtain the point where the click occurred on the bitmap GetCursorPos(&pt); m_periodicBitmap.ScreenToClient(&pt); pDC = m_periodicBitmap.GetDC(); memDC.CreateCompatibleDC(pDC); hOldBMP = memDC.SelectObject(&TemplateBMP); crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y); CString colourString; colourString.Format("Colour clicked: %d", crColourAtPoint); AfxMessageBox(colourString);

                J 1 Reply Last reply
                0
                • B b_girl

                  I'm doing something seriously wrong. No matter where I click on the bitmap, crColourAtPoint is ALWAYS set at 16777215. I don't understand why. CBitmap TemplateBMP; ... TemplateBMP.LoadBitmap(IDB_PERIODIC_TMPL); ... POINT pt; CDC *pDC = NULL; CDC memDC; COLORREF crColourAtPoint = 0; CBitmap *hOldBMP = NULL; //obtain the point where the click occurred on the bitmap GetCursorPos(&pt); m_periodicBitmap.ScreenToClient(&pt); pDC = m_periodicBitmap.GetDC(); memDC.CreateCompatibleDC(pDC); hOldBMP = memDC.SelectObject(&TemplateBMP); crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y); CString colourString; colourString.Format("Colour clicked: %d", crColourAtPoint); AfxMessageBox(colourString);

                  J Offline
                  J Offline
                  Jason Henderson
                  wrote on last edited by
                  #8

                  Make sure your pt.x and pt.y are accurate.

                  "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

                  Jason Henderson
                  blog | articles

                  B 1 Reply Last reply
                  0
                  • J Jason Henderson

                    Make sure your pt.x and pt.y are accurate.

                    "It is better to remain silent and be thought a fool than to open one's mouth and remove all doubt." - Abraham Lincoln

                    Jason Henderson
                    blog | articles

                    B Offline
                    B Offline
                    b_girl
                    wrote on last edited by
                    #9

                    They appear to be. I mean, the values will remain the same if i click in the same spot, and they'll change (in what seems to be correct) if i click in a different spot. Out of all the elements, only 3 of them end up getting a 'matching colour' when they're clicked on. The code that I've cut and pasted into these messages all looks right though doesn't it? Maybe I'll just re-do the template bitmap or something... I don't really know what else to do.

                    1 Reply Last reply
                    0
                    • B b_girl

                      In the interface I'm creating I have a dialog box that opens up containing a bitmap. Something different will happen depending on where on the bitmap the user clicks. I have 2 bitmaps, the "real" and the "template". I don't know why, but when the user clicks on the bitmap, the colour values are being read from the real bitmap and not the template one. I think the problem comes from this bit of code, but I'm not completely sure why: in my constructor: ... HBITMAP hTemplateBMP; hTemplateBMP = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_PERIODIC_TMPL)); ... in my on clicked message handler: POINT pt; CDC *pDC = NULL; CDC memDC; HBITMAP hOldBMP = NULL; COLORREF crColourAtPoint = 0; GetCursorPos(&pt); m_periodicBitmap.ScreenToClient(&pt); pDC = m_periodicBitmap.GetDC(); memDC.CreateCompatibleDC(pDC); hOldBMP = (HBITMAP)memDC.SelectObject(hTemplateBMP); crColourAtPoint = GetPixel(memDC.m_hDC, pt.x, pt.y); ... IDB_PERIODIC_TMPL is the template for my bitmap... I believe crColourAtPoint ends up being the colour of the point in the real bitmap, not the template bitmap. Why??

                      T Offline
                      T Offline
                      Terry ONolley
                      wrote on last edited by
                      #10

                      I've just submitted an article about this. You can check out the demo files/source code at: http://www.bj-consulting.com/tln/pte_demo.zip[^] I didn't go the bitmap route though. It is a really nifty way of determining which element was clicked on, but if you later decided you wanted to include the dicovery date of the element (or any other text) then you would have to edit your bitmap by adding text in 117 different places and when you scaled your window the text would start to look all pixellated and illegible. The code to draw the entire table is only 14 lines and it is scalable as you change the window size. It also highlights all of the elements in the chemical group you have selected with a red border. Right clicking an element adds it to the listbox, double clicking opens a dialog box with the chemical details. Thew controls are also resizable. Oh - it includes an MS-Access database with the elemnt info - you'll need to create an ODBC mapping to the DB - just name the datasource PeriodicTableApp



                      B 1 Reply Last reply
                      0
                      • T Terry ONolley

                        I've just submitted an article about this. You can check out the demo files/source code at: http://www.bj-consulting.com/tln/pte_demo.zip[^] I didn't go the bitmap route though. It is a really nifty way of determining which element was clicked on, but if you later decided you wanted to include the dicovery date of the element (or any other text) then you would have to edit your bitmap by adding text in 117 different places and when you scaled your window the text would start to look all pixellated and illegible. The code to draw the entire table is only 14 lines and it is scalable as you change the window size. It also highlights all of the elements in the chemical group you have selected with a red border. Right clicking an element adds it to the listbox, double clicking opens a dialog box with the chemical details. Thew controls are also resizable. Oh - it includes an MS-Access database with the elemnt info - you'll need to create an ODBC mapping to the DB - just name the datasource PeriodicTableApp



                        B Offline
                        B Offline
                        b_girl
                        wrote on last edited by
                        #11

                        Thanks. I did decide on the bitmap 'route' though. Mainly because the bitmap will only have to display the element symbol (ie. H, C, etc..) and atomic number, and I only ever require to use the element symbol. I know that even in future versions of my interface, there will be no further information required... Although I'm still having problems getting the colours to match up. It only works right for 3/92 elements (93-110 were removed because they won't ever be used for this)...

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups