Sign in to follow this  
AckPacket

Edit Control not showing properly

Recommended Posts

hello everyone. I am making a program to emulate AIM (Aol instant messenger), and plan to use it to find out who has been logging in on my screen name on my computer. But that's beside the point. What i need help with is this. I have placed an edit control on the window, but it's not showing properly. The edit control first appears invisible when the program starts. When i move the mouse over it, the cursor still changed to the i-beam, and if i click, the blinking | cursor appears, so i know the control is there. The control still remains invisible until i type text into it. When i type text into the edit control, the characters appear and only the white inner part of the control appears. If i specify a WS_EX_CLIENTEDGE in the styles, that part never shows up. If i switch focus to another program and switch back to mine, the control is gone again and i have to click in it and type to get the white part to show up again. What could be causing this? You can see the problem for yourself by downloading the exe i compile with this from Http://ackpacket.netfirms.com/fakeaim.exe Also, since the code tags on this forum are totally mangling my code, you can download the source from http://www.ackpacket.netfirms.com/main.cpp Here is the source code, please take a look at it:
#include <windows.h>
#include <winuser.h>
#include <c:\951\c++\fake aim\resource.h>

//constants and variables
const char g_szClassName[] = "myWindowClass";
HBITMAP g_hbmAimSplash = NULL;
#define IDC_EditUserName	101


// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
		
		case WM_CREATE:
		{
			g_hbmAimSplash = LoadBitmap   //load the bitmap
                        (GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1));
			if(g_hbmAimSplash == NULL)
			{

				MessageBox(hwnd, "Could not load IDB_BALL!", "Error", MB_OK | MB_ICONEXCLAMATION);
			}

			HWND hEditUserName;
			hEditUserName = CreateWindowEx(
			WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
			"EDIT",
			"",
			WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL | ES_NOHIDESEL | 00000200,
			22, 170, 163, 16,
			hwnd, (HMENU)IDC_EditUserName, GetModuleHandle(NULL), NULL);
			
			HFONT hfDefault;

			hfDefault = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
			SendMessage(hEditUserName, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
		}
		break;

		case WM_PAINT:
		{
			BITMAP bm; //begin the bitmap
			RECT rect;

	        HDC hdc = GetDC(hwnd);  //begin painting now that i got the window's dc
	
		    HDC hdcMem = CreateCompatibleDC(hdc);
			HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_hbmAimSplash);

			GetObject(g_hbmAimSplash, sizeof(bm), &bm);

			BitBlt(hdc, 8, 5, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY); //bitmap displayed

			SelectObject(hdcMem, hbmOld);
	        DeleteDC(hdcMem);

		    ReleaseDC(hwnd, hdc); //release the windows dc

			//validate the window
			GetClientRect(hwnd, &rect);
			ValidateRect(hwnd, &rect);
		}
		break;
		case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;
    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = CS_OWNDC | CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hinstance;
    wc.hIcon         = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_ICON1));
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(GetStockObject(LTGRAY_BRUSH));
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm       = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_ICON1));

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating the Window
    hwnd = CreateWindowEx(
        0,
        g_szClassName,
        "Sign On",
		WS_OVERLAPPEDWINDOW ^ WS_MAXIMIZEBOX ^ WS_THICKFRAME,
        CW_USEDEFAULT, CW_USEDEFAULT, 212, 385,
        NULL, NULL, hinstance, NULL);

    if(hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}



I am using microsoft visual c++ 6.0, and if you would like to try the code for your self, make sure you take out the include for the resource header, and to change the icon to a standard icon, and take out the part that displays the bitmap. Basically take out any reference to resources you don't have. Also, i should discuss the method i am using for paint, because it might make a difference. Instead of using begin paint and end paint to paint only a section of the window, i use getdc() to get the whole window, paint, and then releasedc(). Since this does not validate the window, i use GetClientRect() and ValidateRect() to make sure the window is validated. I have tried switching to the BeginPaint() EndPaint() method and this does not solve my problem. [Edited by - AckPacket on August 17, 2004 3:53:24 AM]

Share this post


Link to post
Share on other sites
You could try InvalidateRect or something just after Updating the window.

As for your overall aim, you might want to investigate getting a "keylogger" or doing a low-level keyboard hook yourself.

Or you could try and inject your own code by replacing the WinProc using set win proc or similar. Depends on what platform you are on as to what you can do though really.

Though from your WM_PAINT you actually aren't ever telling your child controls to draw themselves. You might be better off overriding the background paint message with your bitmap drawing.

Share this post


Link to post
Share on other sites
Yes, I think the problem is in the WM_PAINT handler.

At the moment, you're handling the WM_PAINT for your bitmap, but not drawing anything else. You're also returning 0 which is like saying to windows "I've finished handling this WM_PAINT message, so you don't need to worry about it". I think if you return non-zero, the control's own handler for the WM_PAINT should get called, failing that, use CallWindowProc() with the default window handler (DefWindowProc) to make everything behave nicely.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sandman
Yes, I think the problem is in the WM_PAINT handler.

At the moment, you're handling the WM_PAINT for your bitmap, but not drawing anything else. You're also returning 0 which is like saying to windows "I've finished handling this WM_PAINT message, so you don't need to worry about it". I think if you return non-zero, the control's own handler for the WM_PAINT should get called, failing that, use CallWindowProc() with the default window handler (DefWindowProc) to make everything behave nicely.


Thank you, you seem very helpful. I'm still having some difficulty however, could you possibly show an example with a snippet or maybe post the altered code? Feel free to try altering the code and running it yourself, i've put the executable on the net at the address i said earlier, and now the address is working. There you can see exactly what happens. Any help you can provide would me much appreciated :).

[Edited by - AckPacket on August 17, 2004 3:51:29 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by AckPacket
Thank you, you seem very helpful. I'm still having some difficulty however, could you possibly show an example with a snippet or maybe post the altered code? Feel free to try altering the code and running it yourself, i've put the executable on the net at the address i said earlier, and now the address is working. There you can see exactly what happens. Any help you can provide would me much appreciated :).


On more careful examination, it looks like the you're validating the area too aggressively in your WM_PAINT. What's happening is you're validating the whole window, rather than just the bit you've updated, and as a result, the edit box thinks it's already been drawn.

Just validate the bit you've changed, and it should work fine, with or without WS_EX_CLIENTEDGE.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this