Thread: Help on SelectObject() function...

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    610

    Help on SelectObject() function...

    I'm struggling to understand the use of this function... Here's an example code

    Code:
    HDC hMemDC;
    HBITMAP hBmp, hOldBmp;
    
    hBmp = Earth.GetHandle ();
    
    // Draw a line through the graphic file
    hMemDC = CreateCompatibleDC(0);
    hOldBmp = SelectObject (hMemDC, hBmp);
    
    MoveTo (hMemDC, 0, 20);
    LineTo (hMemDC, 30, 50);
    
    SelectObject (hMemDC, hOldBmp);
    
    DeleteDC (hMemDC);
    
    // Show changes
    Earth.Repaint ();
    }
    SelectObject() is used twice, but i fail to understand the use of it.. The code draws a line through an Earth object (Bitmap)...

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The second call to SelectObject restores the old previously selected object - it may well be "nothing", but it's going to break if someone else had selected an object for that DC elsewhere and then called this function.

    MSDN's documentation of SelectObject:
    http://msdn2.microsoft.com/en-us/lib...72(VS.85).aspx
    says:
    This function returns the previously selected object of the specified type. An application should always replace a new object with the original, default object after it has finished drawing with the new object.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by matsp View Post
    The second call to SelectObject restores the old previously selected object - it may well be "nothing", but it's going to break if someone else had selected an object for that DC elsewhere and then called this function.

    MSDN's documentation of SelectObject:
    http://msdn2.microsoft.com/en-us/lib...72(VS.85).aspx
    says:


    --
    Mats
    So, the 1st SelectObject() selects an image "hBmp" to memory DC and saves it as "hOldBmp", then the second one restores "hOldBmp"? please clarify the reason behind all this....

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It saves WHAT the OLD selected bitmap for that DC was, and then restores it when it's finished.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    214
    That code is drawing to a memory Device Context (DC). The initial bitmap in a memory DC is a placeholder, one pixel by one pixel. In order to do drawing you have to select a bitmap into the DC with the desired dimensions. This gets the bitmap.

    Code:
    hBmp = Earth.GetHandle ();
    Selects it into memDC
    Code:
    hOldBmp = SelectObject (hMemDC, hBmp);
    The second call to SelectObject is doing what matsp said.
    Last edited by DaveH; 04-08-2008 at 07:13 AM.

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Thanks for the info guys, but let me extend to help identify my confusion...

    I have a frame window (640x480)... I have inserted an image into it (151x153)... The code above draws a line from within the center of the image regardless of its position on the frame, this with the help of the two lines
    Code:
    MoveTo (hMemDC, 0, 20); // Start point of line
    LineTo (hMemDC, 30, 50); // End point of line
    Question? Why is the XY points of the line draws only within the Image boundries not the entire frame? Which of the functions (from the code snippet) ensures that the line is only drawn within the parameters of the (151x153) image? I think this is what am trying to understand....

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    214
    I assume that

    Code:
    hBmp = Earth.GetHandel ();
    
    hOldBmp = SelectObject (hMemDC, hBmp);
    are selecting your inserted image. And the moveto, lineto are drawing on it. The coordinates in the MoveTo, LineTo are for the bitmap selected into the memory dc, not the frame window. Without seeing the full drawing code thats just a guess.

  8. #8
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by DaveH View Post
    I assume that

    Code:
    hBmp = Earth.GetHandel ();
    
    hOldBmp = SelectObject (hMemDC, hBmp);
    are selecting your inserted image.
    Correct!

    And the moveto, lineto are drawing on it. The coordinates in the MoveTo, LineTo are for the bitmap selected into the memory dc, not the frame window.
    Make sense...

    Without seeing the full drawing code thats just a guess.
    The code i gave to you is a complete code for this task...

    The following statements...
    Code:
    SelectObject (hMemDC, hOldBmp);
    
    DeleteDC (hMemDC);
    deletes the old image from memory, is that correct? But then, what about the current image? just don't understand the reasoning behind hOldBmp vs hBmp... is the hBmp the new image with the line drawn and hOldBmp the original...?

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    214
    Code:
    hOldBmp = SelectObject (hMemDC, hBmp);
    Selects the new bitmap and stores the original bmps handle into hOldBmp.

    Code:
    SelectObject (hMemDC, hOldBmp);
    Selects the original bitmap back into the DC.

    Code:
    DeleteDC (hMemDC);
    Deletes the memory dc.

    The current image is the bitmap you got using Earth.GetHandle(). But without seeing that code I don't know what its actually doing. hBmp is the handle to the bitmap in the Earth object. hOldBmp is the handle to the dc's bitmap being replaced by SelectObject. According to the documentation, an application should always replace a new object with the original, default object after it has finished drawing with the new object.
    Last edited by DaveH; 04-08-2008 at 08:46 AM.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    Quote Originally Posted by DaveH View Post
    Code:
    hOldBmp = SelectObject (hMemDC, hBmp);
    Selects the new bitmap and stores the original bmps handle into hOldBmp.
    By Original you referring to an empty/blank frame, since there was not image before inserting the earth?

    Code:
    DeleteDC (hMemDC);
    Deletes the memory dc.
    So Dave, after this line, i may not draw anything to the earth image? meaning i would have to select it again, or maybe get its handle again ... I'm learning a lot from this and please don't loose patience with me


    According to the documentation, an application should always replace a new object with the original, default object after it has finished drawing with the new object.
    Two questions, probably last ones...

    1. I would like to draw different lines at different times (i.e At first a horizontal line across the image, after 5 seconds a vertical line across the image... I plan to then loop the following function twice ...
    Code:
    // Function to draw line on the image
    void DrawLine(POINTS coord, POINTS factor)
    {
         hBmp = Earth.GetHandle();
    
         hOldBmp = SelectObject(hMemDC, hBmp);			
    
         MoveToEx(hMemDC, coord.x, coord.y, &myPoint);		
         LineTo(hMemDC, coord.x+factor.x, coord.y+factor.y);	
    
         SelectObject (hMemDC, hOldBmp);					
         DeleteDC (hMemDC);								
    }
    Q. My only concerns in the code are: If DeleteDC deletes memory DC, calling DrawLine for the second time requires me to first GetHandle of the image, then selectObject, after drawing delete it again (as i have done in the code).. Is this correct (looping the above code)....?

    2. After drawing a line in the image, how do i save the new image with the newly drawn line, such that i can continue adding more line...

    Thanks a lot Dave
    Last edited by csonx_p; 04-09-2008 at 12:55 AM.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    a memory DC is a "device context", which is essentially the settings and other "knowledge" the graphics subsystem needs to be able to draw to a bitmap. It is NOT the bitmap itself - that is your "earth" object. So deleting this will not affect the bitmap itself, only the device context that is used to help you draw to the bitmap.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Apr 2008
    Posts
    610
    One more question on the SelectObject() function and DC... In my example code, i would like to loop the entire code that i continue drawing different lines in the same bitmap. But, i would like the previous line not to show... Currently all lines drawn do show for every call of Earth.Repaint()... Does this mean now the line drawn is part of the Bitmap drawn to it. is this what MoveToEx & LineTo on DC does..? One example would be to flash/flick a line in different positions of the Bitmap...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  3. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM