Thread: pixel manipulation troubles.

  1. #1
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67

    pixel manipulation troubles.

    alright, i've totally gotten myself lost. my goal is to make some sort of trajectory program on a windows application, where you can simply see a ball fired from a cannon travel different arcs. I'm far far away from fufilling that dream, as I've never programmed anything on a GUI before, at least in c++.
    My first step was to actually figure out how you put different pixel colors on the screen. So, not wanting to bother you guys, I went to the msdn library, which i have no idea how to use, and i found this about pixel manipulation. it looks like a rather slow way to manipulate a lot of pixels, but oh well, i was just going to give it a shot. I've got a few hang-ups though. at the bottom, it says:
    " Header: Declared in Wingdi.h; include Windows.h."
    I know what "include" means, but what does "Declared in Wingdi.h" mean? is it important? Also, under that i see where it tells me to use Gdi32.lib. I know how to add libraries, but I don't have any experience using them, and I don't know where to get that particular one. Help?
    also, if someone could explain a better way to actually manipulate pixels, that'd also be a great help.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    Declared in wingdi.h means that SetPixel function prototype is in wingdi.h. Since wingdi.h is being included by windows.h (or some other header file that is included by windows.h) then you only need include windows.h to use this function.

    Your compiler should come with GDI32.lib and probably links to it by default. The library contains the compiled code of the functions, you don't have to do anything other then link to it.

  3. #3
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67
    i did a search on my computer for that file and didn't find it, and the function wont work if i just try to do it by itself without worrying about the file. I can probably get it off of a p2p program pretty quickly though, do you think?

    also, could could you show an example of how that code works? I'm also not sure exactly if i'm doing it right. I put it in the correct format as it says in the msdn library, but do i like, need to declare a function beforehand or something?

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    Actually my earlier post wasn't quite correct. The .lib file dosen't contain the code, the code is in a .dll and the .lib is needed to link to the dll but that dosen't change anything here.

    If you're using dev-cpp then maybe the library's name is gdi32.a

    Call GetDC To get the hdc to pass to SetPixel. You should do this within a BeginPaint EndPaint block in response to WM_PAINT.

  5. #5
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67
    pardon my noobness, but, you kinda lost me

    Call GetDC To get the hdc to pass to SetPixel. You should do this within a BeginPaint EndPaint block in response to WM_PAINT.
    ok, firstly, where and how do i call GetDC?
    secondly, where and how do i put the BeginPaint and EndPaint blocks?

    Edit: by the way, the library is included by default, it just had the .a name, and my code was written a bit wrong, further throwing me off. I did manage to get the program to run without errors, but the one pixel didn't show up, probably because i didn't use any of that beginpaint and endpaint stuff
    Last edited by n3v; 04-27-2006 at 03:01 AM.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    Here's a quick example
    Code:
    LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
       switch(uMsg)
       {
          case WM_PAINT:
          {
    	HDC hDC=GetDC(hWnd);
    	PAINTSTRUCT ps;
    	BeginPaint(hWnd, &ps);
    	SetPixel(hDC, 10, 10, (COLORREF)0xffffffff);
    	EndPaint(hWnd, &ps);
         }
           break;
         case WM_DESTROY:
    	PostQuitMessage(0);
    	break;
       }
    }
    Last edited by Quantum1024; 04-27-2006 at 03:14 AM.

  7. #7
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67
    more retarded questions:

    alright, so if i had that same code, where would i put it? under everything else? I also have to previously declare a function like that, dont i? then, how would i call it? and when? I'm a total noob to gui programming, i've only done command line and vb. help would be vastly appreciated. also, in that function you gave me as an example, explinations of what it's actually doing (besides the setpixel part, i get that) would also be Really appreciated.

    Edit: nevermind, i got a tutorial, and i figured out how to use the function. thanks for your time and patience.
    Last edited by n3v; 04-27-2006 at 03:40 AM.

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    have you created a main window, message loop and window procedure yet?

    The code I gave is a window procedure if you've created a window you should have a function that looks a lot like it.

    The switch statement only handles 2 window messages WM_PAINT and WM_DESTROY. WM_PAINT is sent to your window's window procedure everytime the window needs to be redrawn.
    EDIT:
    OK

  9. #9
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67
    well, the thing is, i'm such a n00b, i didn't really understand what you meant with any of that syntax at first, but running through a simple tutorial showed me how to handle messages and stuff (something i really wasn't accustomed to).

    i got all of that to work; i got my one pixel to pop up, now i'm going one step further. I'm trying to tie it into a loop, as to make more than one pixel. here's my code so far from my main window:

    Code:
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                 
        {
               case WM_PAINT:
          {
    	HDC hDC=GetDC(hwnd);
    	PAINTSTRUCT ps;
    	BeginPaint(hwnd, &ps); 
    	SetPixel(hDC, 100, 100, (COLORREF) 0xffffffff);
    	EndPaint(hwnd, &ps);
         }
       break;
            case WM_DESTROY:
                PostQuitMessage (0);       
                break;
            default:                     
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    I'm guessing that i'd need to throw a for statement in there somewhere, but i don't really know where. i tried a few experiments, but nothing happened. i either got an error, or no pixels at all. suggestions?

    i think i'll need to make a loop somewhere else, generating the coordinate values, then feed them via messages to there. I'm probably wrong though. can you help?

    EDIT:

    I did manage to get it to work, putting the loop before the beginpaint statement, and ending it after the endpaint statement, this code gave me a straight line on my form:
    Code:
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)                  
        {
               case WM_PAINT:
          {
    	HDC hDC=GetDC(hwnd);
    	PAINTSTRUCT ps;
    	for (int n = 30; n < 60; n++) {
    	BeginPaint(hwnd, &ps);
    	SetPixel(hDC, n, 100, (COLORREF) 0xffffffff);
    	EndPaint(hwnd, &ps);
    }
         }
       break;
            case WM_DESTROY:
                PostQuitMessage (0);      
                break;
            default:                      
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }
    is this the best way to do it?
    Last edited by n3v; 04-27-2006 at 04:34 AM.

  10. #10
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    There's some stuff that you need to do to make a normal window (as opposed to a console window). You can actually do drawing in the console, though. For example:
    Code:
    #define _WIN32_WINNT 0x0500 //runs on XP, 2000 Pro, or Vista
    #include <windows.h>
    
    
    int main()
    {
      HWND hwnd = GetConsoleWindow(); //get handle to the console window
      HDC hdc = GetDC(hwnd); //get device context (for drawing)
      RECT rc; 
      GetClientRect(hwnd,&rc); //get dimensions of the console screen area
      while (!(GetAsyncKeyState(VK_RETURN)&0x8000)) //run until enter is pressed
      {
        //do some drawing stuff
        static int x=0,y=0;
        SetPixel(hdc,rc.left+x,rc.top+y,RGB(255,255,255));
        x++;
        x%=rc.right;
        y++;
        y%=rc.bottom;
      }
      ReleaseDC(hwnd,hdc); //release the device context
    }
    I believe you need to link to libkernel32.a and libgdi32.a (with dev-c++)

    If you want to learn more about GUI apps, then I'd suggest looking for a windows tutorial, which will describe how to set up your window.

    Edit: I think The Forger is often recommended as a starting point to learn the Win32 API.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    847
    Quote Originally Posted by n3v
    is this the best way to do it?
    You should call BeginPaint/EndPaint outside the loop
    Code:
     switch (message)                  
        {
               case WM_PAINT:
          {
    	HDC hDC=GetDC(hwnd);
    	PAINTSTRUCT ps;
    	BeginPaint(hwnd, &ps);
    	for (int n = 30; n < 60; n++) 
                       SetPixel(hDC, n, 100, (COLORREF) 0xffffffff);
    	EndPaint(hwnd, &ps);
    
         }

  12. #12
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I think I read through your post too quickly when made my last post. For some reason, I thought you hadn't even figure out how to make your main window. So I guess I wasn't very helpful at all
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  13. #13
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67
    well, i'm coming along a bit i guess, i figured out how to get the program to draw straight lines illustrating different angles, but when i actually get to making an arc path, like for a cannonball, i'm getting stuck a little again.
    i did a little poking around in the msdn about curved lines and stuff, and i found information on the bezier curve, which i tried to implement. it seems to do a similar-looking curve to what i want, and even looks accurate with some angles (the nearer to 45 degrees, the more accurate).
    Instead of trying to explain my confusing code, I'll just ask: before i go through a bunch of trouble trying to fix this curve, is it the right way i should try to show a curve like this? is there a better way?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Changing pixel colour
    By redruby147 in forum C Programming
    Replies: 11
    Last Post: 06-09-2009, 05:28 AM
  2. How can I make this code more elegant?
    By ejohns85 in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2009, 08:55 AM
  3. Reading pixel color data from screen
    By JJFMJR in forum Windows Programming
    Replies: 8
    Last Post: 08-22-2008, 12:27 PM
  4. Getting Pixel Colour Screen
    By god_of_war in forum C++ Programming
    Replies: 3
    Last Post: 03-14-2006, 01:17 PM
  5. Creating pixel graphics in MFC
    By Kristian25 in forum Windows Programming
    Replies: 2
    Last Post: 01-09-2003, 01:39 PM