Results 1 to 17 of 17

Thread: Skinning Tutorials

  1. #1

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Skinning Tutorials

    Can Anybody Direct Me To Information On Skinning In C++ using API only ??? Perferably the same way Winamp does its skinning or something similiar, any help would be appreciated.

    Thanx for any help.
    AAG

  2. #2
    Hyperactive Member Amon Ra's Avatar
    Join Date
    Feb 2001
    Location
    In some cave on Uranus...
    Posts
    500

    Unhappy Hrmmm

    I have been looking for the same info, but...never found it. Let's hope from here has it
    Amon Ra
    The Power of Learning.

  3. #3
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    What you are asking is a huge request.

    The way that winamp skins work:

    BitBlt the main image on an empty window
    BitBlt the buttons, bars, etc over the top of that

    All these imges have a certian X/Y system which is fixed to match the X and Y from the main bmp file and the X and Y of the BitBlt pos on the form.

    There is also a X/Y system that keeps track of the X/Y of all the things on the screen that can change, buttons, bars, etc. When a user clicks in an area that matchs the X/Y that system knows it has to change, it BitBlt the changed image over the top of the coressponding pos on the window, until the user releases the button. Then runs the function that coresponds what was pushed, like stop.

    Thats the bare basics of how the skins works. Its really complex, believe me I made a MP3 player that used winamp skins.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  4. #4

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Cool

    Well could you possibly send me some sample sourcecode of your mp3 player. I'm creating a full fledged media player, and i would like to create skins for it. All i need is just a form with a skinned button on it, and i can figure out the rest. Or could you possibly give me another way to do the skinning. how would I go about detecting what hwnd the mouse is over when its down. Do I use the wParam in the WM_LBUTTONDOWN ??

  5. #5
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Sorry about my last post I rushed through it, there was only 2 mins before I left work

    My player, which is prob only 50% done, I made in VB. But I can help you with what you need to do in C++.

    Do you know how to use BitBlt? I sure hope so because I am going to skip how to use it. If you need help with using it let me know and I will help you with that too.

    If you open a .wsz file, which is just a renamed .zip file, you will see all the .bmp files that make up a winamp skin. If you look at main.bmp you will see the main boby image for winamp. It is about 275x116. So what you need to do is make a window with no caption, no control buttons, etc. Basically a really blank window. It should be 275x116 of course.

    Then make a static control that will cover the whole window. Use the SS_REALSIZEIMAGE in your flags on create window. Then BitBlt the main.bmp on to the static control.

    Then lets say you want to have the play button on it. Most of those buttons are in CButton.bmp. You will see that there are 2 sets of buttons. The top set, is the up position buttons. The bottom set, is the down position buttons. Each button I think is 19x18 with 2 pixels in between each button. Its real easy to BitBlt the up buttons with a loop, skiping 2 pixels after each button.

    So back to play, lets say you BitBlt that button to position (I am just going to make it up because I dont have my orginal player here right now. But you are going to have to play with were you position your buttons until you get them aligned) 10X10. What you need to do is use WM_LBUTTONDOWN and WM_BUTTONUP in you Message function.

    Basically the function would look like this:

    PHP Code:
    case WM_LBUTTONDOWN:
    {  
    //Not needed
      
    if(hWnd == ThehWndOfYourStaticControl)
       {
         
    POINT pt;
         
    pt.LOWORD(lParam);
         
    pt.HIWORD(lParam);
         
    GetButtonClicked(pttrue);      //This is a function I made to handle just the buttons
         
    break;
       }
       break;
    //Not needed

    case WM_LBUTTONUP:
    {  
    //Not needed
      
    if(hWnd == ThehWndOfYourStaticControl)
       {
         
    POINT pt;
         
    pt.LOWORD(lParam);
         
    pt.HIWORD(lParam);
         
    GetButtonClicked(ptfalse);      //This is a function I made to handle just the buttons
         
    break;
       }
       break;
    //Not needed 
    Here is what that function looks like:

    PHP Code:
    void GetButtonClicked(POINT ptbool Down)
    {
      
    //Remeber we put the button at 10x10
      //So if the mouse is clicked somewhere between 10-29 on the x (Remeber the button is 19 pixels wide)
      //And if it clicked somewhere between 10-28 on the y (18 pixles long)
      
    if(((pt.>= 10) && (pt.<= 29)) && ((pt.>= 10) && (pt.<= 28)))
      {
        if(
    Down)  //We pass in a bool to see if the button is pushed down or not)
           
    BitBltTheDownButton();
        else
        {
          
    BitBltTheUpButton();
          
    Sleep(0);    //Make Sure BitBlt Finshed Before Moving On
          
    PlayMusic();
        }
      }

    Well thats the jist of it. Thats prob more than you wanted to know, but I rather give more info than to little.

    I wrote all the code by hand and all the skin info from memory so there maybe some mistakes there.

    Let me know if you need anymore help.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  6. #6
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Oh and here is a tip that I have learned the hard way many, many times, doing skins. Either do the exit buttons first. Or build in a case statement that will run your exit functions on any button pushed, or when the left mouse button is clicked on the form and is not in a button area. If you don't then its hard to close the window, and if you dont destory your hDCs, hBitmaps, etc your going to memory leak everywhere.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  7. #7

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Thanx

    I didn't need as much information as you gave me. I've created winamp skins before and have created a full fledged MP3 Player in vb6 using the MCI API that was almost completely compatible with winamp skins, there were a couple of things i hadn't implemented yet, but it even bitblt the skinned fonts . I just wasn't sure what exactly I was supposed to be handling in C++. Thanx for the info.

    AAG

  8. #8
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    I got mine to do all the skin, up and down. It was a perfect match with winamp except for that second before VB BitBlt'd the image. I never finished doing any of the abilities, VB is just to weak to handle most of that stuff well.

    If nothing else maybe someone else can use all that info.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  9. #9

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Ok Now I'm getting fustrated. LOL

    Ok I don't know why this isn't working. It was working when I tried it a while back. here's my code.

    Code:
    #include <windows.h>
    #include "resource.h"
    
    static char g_szClassName[] = "MyWindowClass";
    static HINSTANCE g_hInst = NULL;
    
    HBITMAP MainBitmap;
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
    {
       switch(Message)
       {
          case WM_CREATE:
             MainBitmap= LoadBitmap(g_hInst, "MAIN_BITMAP");
             if(!MainBitmap){
                MessageBox(hwnd, "Resource Loading failed.", "Oops",
                   MB_OK | MB_ICONEXCLAMATION);
             }
          break;
          case WM_PAINT:
             if(MainBitmap)
             {
                PAINTSTRUCT ps;
                HDC hdcMemory, hdcWindow;
                BITMAP bm;
    
                hdcWindow = BeginPaint(hwnd, &ps);
                hdcMemory = CreateCompatibleDC(hdcWindow);
    
                SelectObject(hdcMemory, MainBitmap);
                GetObject(MainBitmap, sizeof(bm), &bm);
                
                BitBlt(hdcWindow, 0, 0, bm.bmWidth, bm.bmHeight, hdcMemory, 0, 0, SRCCOPY);
                DeleteDC(hdcMemory);
                EndPaint(hwnd, &ps);
             }
          break;
          case WM_CLOSE:
             DestroyWindow(hwnd);
          break;
          case WM_DESTROY:
             DeleteObject(MainBitmap);
             PostQuitMessage(0);
          break;
          default:
             return DefWindowProc(hwnd, Message, wParam, lParam);
       }
       return 0;
    }
    
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
       LPSTR lpCmdLine, int nCmdShow)
    {
       WNDCLASSEX WndClass;
       HWND hwnd;
       MSG Msg;
    
       g_hInst = hInstance;
    
       WndClass.cbSize        = sizeof(WNDCLASSEX);
       WndClass.style         = NULL;
       WndClass.lpfnWndProc   = WndProc;
       WndClass.cbClsExtra    = 0;
       WndClass.cbWndExtra    = 0;
       WndClass.hInstance     = g_hInst;
       WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
       WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
       WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
       WndClass.lpszMenuName  = NULL;
       WndClass.lpszClassName = g_szClassName;
       WndClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
       if(!RegisterClassEx(&WndClass))
       {
          MessageBox(0, "Could Not Register Window", "Oops",
             MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
          return 0;
       }
    
       hwnd = CreateWindowEx(
          WS_EX_CLIENTEDGE,
          g_szClassName,
          "Test",
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, CW_USEDEFAULT, 320, 240,
          NULL, NULL, g_hInst, NULL);
    
       if(hwnd == NULL)
       {
          MessageBox(0, "ERROR Window Was Not Created", "Oops",
             MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
          return 0;
       }
    
       ShowWindow(hwnd, nCmdShow);
       UpdateWindow(hwnd);
    
       while(GetMessage(&Msg, NULL, 0, 0))
       {
          TranslateMessage(&Msg);
          DispatchMessage(&Msg);
       }
       return Msg.wParam;
    }
    I've also inlcuded the project that I did. Its probably the wrong way to do bitblt or something in c++. I forgot where I learned this, I think it was from winprog.org, but not sure.
    Attached Files Attached Files

  10. #10
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Thanks for posting the .zip because I would missed it without it.

    You were real close change:

    PHP Code:
    MainBitmapLoadBitmap(g_hInstMAKEINTRESOURCE(MAIN_BITMAP)); 
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  11. #11
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Opps got a memory leak. Add:

    PHP Code:
    DeleteDC(hdcWindow); 
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  12. #12

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Not Working.

    Ok, The Images are displaying fine, but when I attempt to handle the WM_LBUTTONDOWN message, it does nothing. This is the exact code I have in the WM_LBUTTONDOWN

    Code:
    case WM_LBUTTONDOWN:
       if(hwnd == static1)
       {
          PostQuitMessage(0);
       }
    break;
    I don't know why it doesn't do anything. do You ?? Below Is The Code I Used To Create The Static Control.

    Code:
    #define ID_STATIC1 9001;
    HWND static1;
    
    static1 = CreateWindow("Static", NULL, WS_CHILD | WS_VISIBLE | SS_REALSIZEIMAGE ,0,0,200,25,hwnd,(HMENU)ID_STATIC1,g_hInst,0);

  13. #13
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Can you .zip it again and post it
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  14. #14

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Heres The Zip

    I've attatched the zip below.
    Attached Files Attached Files

  15. #15
    Hyperactive Member Amon Ra's Avatar
    Join Date
    Feb 2001
    Location
    In some cave on Uranus...
    Posts
    500

    Exclamation Hrmm

    I don't think that is the way to control a click event
    the hwnd you are using is the one from the window

    try something like:

    Code:
     if((HWND)lParam == static1)
    {
    }
    Amon Ra
    The Power of Learning.

  16. #16

    Thread Starter
    Hyperactive Member AAG's Avatar
    Join Date
    Aug 2000
    Location
    United States
    Posts
    411

    Nope.

    Still Didn't work
    This Business Is Binary. Your a 1 or a 0. Alive or Dead. (AntiTrust)

  17. #17
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Sorry it's been awhile since I have done this so I missed something. If you make your window and static control the same size you can just use WM_LBUTTON because nothing else on the window will send that message. If you want your static control to deal with the message you need add the flag SS_NOTIFY:

    PHP Code:
    static1 CreateWindow("Static",NULL,WS_CHILD WS_VISIBLE SS_REALSIZEIMAGE SS_NOTIFY,0,0,600,600,hwnd,NULL,g_hInst,0); 
    Then the notification will go to WM_COMMAND:

    PHP Code:
    case WM_COMMAND:
            case 
    STN_CLICKED:
                
    PostQuitMessage(0);
              break; 
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width