Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Creating an Edit Box (Subclassing)

Sonx_hvn7Sonx_hvn7 Member Posts: 54
The code below is my first attempt to create an edit box, i've used three files "SubClassedEditProc.cpp", "subclassing.cpp", and "SubclassedEditProc.h"

BTW these should be .c files, yet struggling to compile C files in VS 2005, get lots of errors.

Subclassing.cpp..

[code]
#include "stdafx.h"
#include

#include "SubclassedEditProc.h" // we need the 'oldEditProcedure' variable

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
{
HWND edit = CreateWindowEx (WS_EX_ACCEPTFILES,TEXT("EDIT"),
TEXT("You can drag and drop a file here..."),
WS_VISIBLE | WS_CHILD | WS_BORDER |
ES_AUTOHSCROLL | ES_LEFT,
10, 10,
300, 22,
hwnd,
0,
HINSTANCE)GetModuleHandle (0),
0
);

oldEditProcedure = (WNDPROC)GetWindowLongPtr (edit, GWLP_WNDPROC);

SetWindowLongPtr (edit, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
break;
}

case WM_DESTROY:
PostQuitMessage (0);
break;

default:
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}
[/code]


SubClassedEditProc.cpp
[code]
#include "stdafx.h"
#include

#define WIN32_LEAN_AND_MEAN

#include "SubclassedEditProc.h"

WNDPROC oldEditProcedure = 0;

LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

switch (message)
{
case WM_DROPFILES:
{
HDROP hDrop = (HDROP)wParam;
TCHAR buffer[MAX_PATH];
int nFilesDropped = DragQueryFile (hDrop, 0, buffer, MAX_PATH);

if (nFilesDropped) {
SetWindowText (hwnd, buffer);
}

DragFinish (hDrop);
return 0;
}

default:

if (oldEditProcedure) {
return CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam);
}
else {
return DefWindowProc (hwnd, message, wParam, lParam);
}
}
}
[/code]


header file
[code]
/*
This is SubclassedEditProc.h
*/

#ifndef __SUBCLASSED_EDIT_H_INCLUDED__
#define __SUBCLASSED_EDIT_H_INCLUDED__

#include

// the pointer to the edit's old window procedure
// this will be used to call the old procedure inside the new window procedure
extern WNDPROC oldEditProcedure;

// the new edit's window procedure prototype
LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

#endif
[/code]

[color=Red]
Problems... Link Error
[/color]
[code]
error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup
[/code]

[color=Blue] Not sure whether is looking for WinMain() or main() function????[/color]


«1

Comments

  • DonotaloDonotalo Member Posts: 715
    do you have WinMain() function? a win32 application needs WinMain() which resembles main() in C/C++.
    [hr][purple]~Donotalo()[/purple]
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54
    : do you have WinMain() function? a win32 application needs WinMain()
    : which resembles main() in C/C++.
    : [hr][purple]~Donotalo()[/purple]

    No i don't.. not sure what should WinMain() contain since the window is created inside the newEditProcedure() function

    [code]
    case WM_CREATE:
    {
    HWND edit = CreateWindowEx (WS_EX_ACCEPTFILES,TEXT("EDIT"),
    TEXT("You can drag and drop a file here..."),
    WS_VISIBLE | WS_CHILD | WS_BORDER |
    ES_AUTOHSCROLL | ES_LEFT,
    10, 10,
    300, 22,
    hwnd,
    0,
    HINSTANCE)GetModuleHandle (0),
    0
    );

    oldEditProcedure = (WNDPROC)GetWindowLongPtr (edit, GWLP_WNDPROC);

    SetWindowLongPtr (edit, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
    break;
    }
    [/code]

    [color=Blue]got the following example somewhere, but not sure what to add or remove from it...[/color]

    [code]
    //Main window
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    {
    InitCommonControls();
    ghInstance=hInstance;
    DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),
    NULL,MainDlgProc);
    return 0;

    }
    [/code]

  • DonotaloDonotalo Member Posts: 715
    creating a window is not sufficient to display a window. functions like ShowWindow() should be called to display a window. you first need to know the basics of making a simple window and displaying it. i don't think you can display an edit box without a visible parent window. there are many other things should be handled such as registering a window. google for win32 tutorial and learn how to create and display a simple window first. learn about WinMain() and main window procedure etc.
    [hr][purple]~Donotalo()[/purple]
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    : : do you have WinMain() function? a win32 application needs WinMain()
    : : which resembles main() in C/C++.
    : : [hr][purple]~Donotalo()[/purple]
    :
    : No i don't.. not sure what should WinMain() contain since the window
    : is created inside the newEditProcedure() function
    :
    : [code]:
    : case WM_CREATE:
    : {
    : HWND edit = CreateWindowEx (WS_EX_ACCEPTFILES,TEXT("EDIT"),
    : TEXT("You can drag and drop a file here..."),
    : WS_VISIBLE | WS_CHILD | WS_BORDER |
    : ES_AUTOHSCROLL | ES_LEFT,
    : 10, 10,
    : 300, 22,
    : hwnd,
    : [color=Red]0,[/color]
    [color=Red]For child windows this should be the ID and
    it cannot be zero.[/color]
    : HINSTANCE)GetModuleHandle (0),
    : 0
    : );
    :
    : oldEditProcedure = (WNDPROC)GetWindowLongPtr (edit, GWLP_WNDPROC);
    :
    : SetWindowLongPtr (edit, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
    : break;
    : }
    : [/code]:
    :
    : [color=Blue]got the following example somewhere, but not sure what
    : to add or remove from it...[/color]
    :
    : [code]:
    : //Main window
    : int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    : {
    : InitCommonControls();
    : ghInstance=hInstance;
    : DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),
    : NULL,MainDlgProc);
    : return 0;
    :
    : }
    : [/code]:
    :
    :
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54
    : : : do you have WinMain() function? a win32 application needs WinMain()
    : : : which resembles main() in C/C++.
    : : : [hr][purple]~Donotalo()[/purple]
    : :
    : : No i don't.. not sure what should WinMain() contain since the window
    : : is created inside the newEditProcedure() function
    : :
    : : [code]: :
    : : case WM_CREATE:
    : : {
    : : HWND edit = CreateWindowEx (WS_EX_ACCEPTFILES,TEXT("EDIT"),
    : : TEXT("You can drag and drop a file here..."),
    : : WS_VISIBLE | WS_CHILD | WS_BORDER |
    : : ES_AUTOHSCROLL | ES_LEFT,
    : : 10, 10,
    : : 300, 22,
    : : hwnd,
    : : [color=Red]0,[/color]
    : [color=Red]For child windows this should be the ID and
    : it cannot be zero.[/color]
    : : HINSTANCE)GetModuleHandle (0),
    : : 0
    : : );
    : :
    : : oldEditProcedure = (WNDPROC)GetWindowLongPtr (edit, GWLP_WNDPROC);
    : :
    : : SetWindowLongPtr (edit, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
    : : break;
    : : }
    : : [/code]: :
    : :
    : : [color=Blue]got the following example somewhere, but not sure what
    : : to add or remove from it...[/color]
    : :
    : : [code]: :
    : : //Main window
    : : int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    : : {
    : : InitCommonControls();
    : : ghInstance=hInstance;
    : : DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),
    : : NULL,MainDlgProc);
    : : return 0;
    : :
    : : }
    : : [/code]: :
    : :
    : :
    :

    Hi AsmGuru... 1. would [code] HMENU childMenu 201; [/code] be fair enough for that parameter?
    2. Since this window is a child as you say, should i then create a main window within the WinMain() fucntion... I mean can't i have 1 window to have edit boxes... Still learning subclassing and its use

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    :
    : Hi AsmGuru... 1. would [code]: HMENU childMenu 201; [/code]: be fair enough for that parameter?
    : 2. Since this window is a child as you say, should i then create a
    : main window within the WinMain() fucntion... I mean can't i have 1
    : window to have edit boxes... Still learning subclassing and its use
    :
    :
    [color=Blue]You doing everything right. Your main window is a dialog surface. You created it in WinMain() with DialogBox(). Usually, dialog box initializing event is WM_INITDIALOG message (not the WM_CREATE - this one is for when you create your main window with CreateWindow()/CreateWindowEx())

    So, simply change WM_CREATE to WM_INITDIALOG in your MainDlgProc function and define some non-zero value:
    [code]
    #define IDC_MY_SUBCLASSED_EDIT 2008
    [/code]
    then use it in code, simply typecasting its value to HMENU:
    [code]
    hEdit = CreateWindow ("edit", .... (HMENU) IDC_MY_SUBCLASSED_EDIT, ...);
    [/code]
    When doing subclassing do not forget to call the default edit function - the one which was returned by SetWindowLong().
    [/color]
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54
    [color=Blue]
    When doing subclassing do not forget to call the default edit
    function - the one which was returned by SetWindowLong().
    [/color]
    [B]You mean GetWindowLong();...? could you give me an example perhaps[/B]

    Here are my changes as per your suggestions..

    Subclassing.cpp
    [code]
    #include "stdafx.h"
    #include

    #include "SubclassedEditProc.h"
    [color=Green]#define IDC_MY_SUBCLASSED_EDIT 2008[/color]

    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch (message)
    {
    [color=Green]case WM_INITDIALOG:[/color]
    {
    HWND edit = CreateWindowEx (WS_EX_ACCEPTFILES,TEXT("EDIT"),
    TEXT("You can drag and drop a file here..."),
    WS_VISIBLE | WS_CHILD | WS_BORDER |
    ES_AUTOHSCROLL | ES_LEFT,
    10, 10,
    300, 22,
    hwnd,
    [color=Green](HMENU)IDC_MY_SUBCLASSED_EDIT[/color],
    HINSTANCE)GetModuleHandle (0),
    0
    );

    oldEditProcedure = (WNDPROC)GetWindowLongPtr (edit, GWLP_WNDPROC);

    SetWindowLongPtr (edit, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
    break;
    }

    case WM_DESTROY:
    PostQuitMessage (0);
    break;

    default:
    return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
    }
    [/code]

    SubclassedEditProc.cpp
    [code]
    #include "stdafx.h"
    #include

    #define WIN32_LEAN_AND_MEAN

    #include "SubclassedEditProc.h"

    WNDPROC oldEditProcedure = 0;

    LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

    [color=Red]
    //Main window
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    {
    InitCommonControls();

    // Display the window to the user
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    // Decode and treat the messages
    // as long as the application is running
    while( GetMessage(&Msg, NULL, 0, 0) )
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }

    return 0;
    }
    ?????
    [/color]

    LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {

    switch (message)
    {
    case WM_DROPFILES:
    {
    HDROP hDrop = (HDROP)wParam;
    TCHAR buffer[MAX_PATH];
    int nFilesDropped = DragQueryFile (hDrop, 0, buffer, MAX_PATH);

    if (nFilesDropped) {
    SetWindowText (hwnd, buffer);
    }

    DragFinish (hDrop);
    return 0;
    }

    default:

    if (oldEditProcedure) {
    return CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam);
    }
    else {
    return DefWindowProc (hwnd, message, wParam, lParam);
    }
    }
    }
    [/code]
    [color=Blue]
    Q: I know there's something wrong with WinMain()... WHat do i add/remove from it?
    [/color]


  • LundinLundin Member Posts: 3,711
    : [color=Blue]
    : When doing subclassing do not forget to call the default edit
    : function - the one which was returned by SetWindowLong().
    : [/color]
    : [B]You mean GetWindowLong();...? could you give me an example
    : perhaps[/B]

    [color=Green]Yes, the one from GetWindowLong(). See comments in code below. [/color]


    : SubclassedEditProc.cpp
    : [code]:
    : #include "stdafx.h"
    : #include
    :
    : #define WIN32_LEAN_AND_MEAN
    :
    : #include "SubclassedEditProc.h"
    :
    : WNDPROC oldEditProcedure = 0;
    :
    : LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    :
    : [color=Red]
    : //Main window
    : int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    : {
    : InitCommonControls();
    :

    [color=Green]Creating the window... RegisterClassEx(), CreateWindow() etc.
    [/color]

    : // Display the window to the user
    : ShowWindow(hWnd, nCmdShow);
    : UpdateWindow(hWnd);
    :
    : // Decode and treat the messages
    : // as long as the application is running
    : while( GetMessage(&Msg, NULL, 0, 0) )
    : {
    : TranslateMessage(&Msg);
    : DispatchMessage(&Msg);
    : }
    :
    : return 0;
    : }
    : ?????
    : [/color]
    :
    : LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    : {
    :
    : switch (message)
    : {
    : case WM_DROPFILES:
    : {
    : HDROP hDrop = (HDROP)wParam;
    : TCHAR buffer[MAX_PATH];
    : int nFilesDropped = DragQueryFile (hDrop, 0, buffer, MAX_PATH);
    :
    : if (nFilesDropped) {
    : SetWindowText (hwnd, buffer);
    : }
    :
    : DragFinish (hDrop);
    : return 0;
    : }
    :
    : default:
    :

    [color=Green]
    CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam); /* always call this */
    return DefWindowProc (hwnd, message, wParam, lParam);

    : }

    [/color]
    : }
    : }
    : [/code]
  • Sonx_hvn7Sonx_hvn7 Member Posts: 54
    [color=Green]Here's my complete code..., please check the RED comments[/color]

    [code]
    #include "stdafx.h"
    #include
    #include
    #include
    #include
    #pragma comment( lib, "comctl32.lib" )

    #define WIN32_LEAN_AND_MEAN
    #define IDC_MY_SUBCLASSED_EDIT 2008

    const char *ClsName = "SubClassing";
    const char *WndName = "Edit Box";
    WNDPROC oldEditProcedure = 0;

    LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

    //Main window
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    {
    WNDCLASSEX WndClsEx;
    HWND hwnd;
    MSG Msg;

    WndClsEx.cbSize = sizeof(WNDCLASSEX);
    WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
    WndClsEx.lpfnWndProc = WndProcedure;
    WndClsEx.cbClsExtra = 0;
    WndClsEx.cbWndExtra = 0;
    WndClsEx.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(400));
    WndClsEx.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(200));
    WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClsEx.lpszMenuName = NULL;
    WndClsEx.lpszClassName = ClsName;
    WndClsEx.hInstance = hInstance;
    WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

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

    [color=Red]//... create window is inside WindowProcedure ...[/color]

    ShowWindow(edit, nCmdShow);
    [color=Red]// How do i get edit returned by createWindowEx here? should it be global[/color]
    UpdateWindow(edit);

    while( GetMessage(&Msg, NULL, 0, 0) )
    {
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
    }

    return 0;
    }

    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch (message)
    {
    case WM_INITDIALOG:
    {
    /*
    First we create an edit control...
    */
    HWND edit = CreateWindowEx (
    WS_EX_ACCEPTFILES,
    TEXT("You can drag and drop a file here..."),
    WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | ES_LEFT,
    10, 10, // position
    300, 22, // size
    hwnd,
    (HMENU)IDC_MY_SUBCLASSED_EDIT,
    (HINSTANCE)GetModuleHandle (0),
    0
    );

    oldEditProcedure = (WNDPROC)GetWindowLongPtr (edit, GWLP_WNDPROC);

    SetWindowLongPtr (edit, GWLP_WNDPROC, (LONG_PTR)newEditProcedure);
    break;
    }

    case WM_DESTROY:
    PostQuitMessage (0);
    break;

    default:
    return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
    }

    LRESULT CALLBACK newEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    switch (message)
    {
    case WM_DROPFILES:
    {
    HDROP hDrop = (HDROP)wParam;
    TCHAR buffer[MAX_PATH];
    int nFilesDropped = DragQueryFile (hDrop, 0, buffer, MAX_PATH);

    if (nFilesDropped) {
    SetWindowText (hwnd, buffer);
    }

    DragFinish (hDrop);
    return 0;
    }

    default: [color=Red]// Is this the right place to call oldEditProcedure?[/color]
    if (oldEditProcedure) {
    return CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam);
    }
    else {
    return DefWindowProc (hwnd, message, wParam, lParam);
    }
    }
    }
    [/code]


  • LundinLundin Member Posts: 3,711
    : [color=Red]//... create window is inside WindowProcedure ...[/color]

    The window itself must be created before that, or the WindowProcedure will not be called. Every window has a window procedure, and in order to link them together, the window must exist.

    The CreateWindow inside the window procedure is for the edit box, not for the window on which the edit box sits.

    : [color=Red]// How do i get edit returned by createWindowEx here? should it be global[/color]

    You don't need it in main().


    : default: [color=Red]// Is this the right place to call oldEditProcedure?[/color]


    I just noticed that my previous code posted ended up in the switch-statement. It shouldn't be there, it should be at the end of the function. So at the end of the subclass function, make sure you have these two lines:

    CallWindowProc (oldEditProcedure, hwnd, message, wParam, lParam);
    return DefWindowProc (hwnd, message, wParam, lParam);
«1
Sign In or Register to comment.