Link to home
Start Free TrialLog in
Avatar of pramod_kumar_tk
pramod_kumar_tk

asked on

Three Valuable questions ?


Hi Experts,
1.) How to show a animation gif in a static ctrl ?
2.) How to get MouseOver Events (Static & Edit ) of ctrl in Dialog (Subclassing) not by a derived class ?
3.) It is possible create an exe with 5KB size ? (I had seen an app. that will jerk all windows after it loaded, yeah, It have only 5KB size )


Avatar of Meir Rivkin
Meir Rivkin
Flag of Israel image

for question #2:
overriding onMouseMove of your CDialog won't help u (because when the cursor is over the controls WM_MOUSEOMVE is sent to the controls), and besides create derived class controls u can use TrackMouseEvent check on: http://www.codeproject.com/gdi/mousecapture.asp
Avatar of captainkirk
captainkirk

1) you may have to manually display each frame with a SetBitmap() call - assuming you have converted the gif into separate bitmaps per frame. You might also look into converting the gif into an AVI and using CAnimateCtrl....

3) it may be possible - just design the program with as few libraries as possible, define VC_EXTRALEAN (MFC projects) or WIN32_LEAN_AND_MEAN (any project) to pare out unneeded stuff from Windows headers, get rid of unneeded variables, modularize your code so that repetitive tasks are not dupplicated, etc...
3:
Do not use RTL stuff only native API!
also you have to write your own entry point in the exe.
miqel,
plz, explain it in details.I am a beginner in VC++
Avatar of pramod_kumar_tk

ASKER

Hi Sidqwick,
There is no other methods to get this type of messages other than creating a derived class ?? Can it possible to subclass the controls ?
Hi captainkirk,
#1.) Plz, explain it in  more details.I had a code that will show the first frame of gif  into the dialog boxs background. I wnt to show it in a static ctrl and also the other frames
#3.)I will check ur comments
Hi Miqel,
Tell me the details
ASKER CERTIFIED SOLUTION
Avatar of migel
migel

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi miqel
I had done. but there is no change in size
Do u I want to change some options also ?
plz, kind towards me to explain things.
I am a  beginner in this area
Thanx
pramod kumar
What work your exe do?
Can you show your WinMain?
you also can play with linker options - incremental linking -off
set optimization for minimal exe size and so on
Does your EXE use MFC?
No My exe doesn't use mfc.
When I tried with all this option the exe size is 16 KB.
this my code
#include "stdafx.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                                             LPSTR lpCmdLine, int nShowCmd);
#define SPACECHAR   _T(' ')
#define DQUOTECHAR  _T('\"')  
#ifdef _UNICODE
extern "C" void wWinMainCRTStartup()
#else // _UNICODE
extern "C" void WinMainCRTStartup()
#endif // _UNICODE
{
      LPTSTR lpszCommandLine = ::GetCommandLine();
      if(lpszCommandLine == NULL)
            ::ExitProcess((UINT)-1);  

      if(*lpszCommandLine == DQUOTECHAR)
      {
            
            do { lpszCommandLine = ::CharNext(lpszCommandLine); }
            while((*lpszCommandLine != DQUOTECHAR) && (*lpszCommandLine != _T('\0')));  
            // If we stopped on a double-quote (usual case), skip over it.
            if(*lpszCommandLine == DQUOTECHAR)
                  lpszCommandLine = ::CharNext(lpszCommandLine);
      }
      else
      {
      while(*lpszCommandLine > SPACECHAR)
            lpszCommandLine = ::CharNext(lpszCommandLine);
      }      
      // Skip past any white space preceeding the second token.
      while(*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
      lpszCommandLine = ::CharNext(lpszCommandLine);  
      STARTUPINFO StartupInfo;
      StartupInfo.dwFlags = 0;
      ::GetStartupInfo(&StartupInfo);  
      int nRet = WinMain(::GetModuleHandle(NULL), NULL, lpszCommandLine, (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ? StartupInfo.wShowWindow : SW_SHOWDEFAULT);  
      ::ExitProcess((UINT)nRet);
}


// Global Variables:
HINSTANCE hInst;                                                // current instance
TCHAR szTitle[100]="My Pgm";                              // The title bar text
TCHAR szWindowClass[10]="MyPgm";                        // The title bar text

// Foward declarations of functions included in this code module:
ATOM                        MyRegisterClass(HINSTANCE hInstance);
BOOL                        InitInstance(HINSTANCE, int);

LRESULT CALLBACK      WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
       
      MSG msg;

      // Initialize global strings
      MyRegisterClass(hInstance);

      // Perform application initialization:
      if (!InitInstance (hInstance, nCmdShow))
      {
            return FALSE;
      }


      // Main message loop:
      while (GetMessage(&msg, NULL, 0, 0))
      {
            
            {
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
            }
      }

      return msg.wParam;

}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.

//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
      WNDCLASSEX wcex;

      wcex.cbSize = sizeof(WNDCLASSEX);

      wcex.style                  = CS_HREDRAW | CS_VREDRAW;
      wcex.lpfnWndProc      = (WNDPROC)WndProc;
      wcex.cbClsExtra            = 0;
      wcex.cbWndExtra            = 0;
      wcex.hInstance            = hInstance;
      wcex.hIcon                  = LoadIcon(hInstance, IDI_WINLOGO);
      wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
      wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName      = NULL;
      wcex.lpszClassName      = szWindowClass;
      wcex.hIconSm            = LoadIcon(wcex.hInstance, IDI_WINLOGO);

      return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND      - process the application menu
//  WM_PAINT      - Paint the main window
//  WM_DESTROY      - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
      
      PAINTSTRUCT ps;
      HDC hdc;
      TCHAR szHello[10]="Hello";
      
      switch (message)
      {
      
            case WM_PAINT:
                  hdc = BeginPaint(hWnd, &ps);
                  // TODO: Add any drawing code here...
                  RECT rt;
                  GetClientRect(hWnd, &rt);
                  DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
                  EndPaint(hWnd, &ps);
                  break;
            case WM_DESTROY:
                  PostQuitMessage(0);
                  break;
            default:
                  return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

I also set project->settings->link->output option ->Entry point -> WinMainCRTStartup
Hey!
I am so impressed!
I take your code and make exe only 1760 bytes long!
give me your EMail i will send my project to you
Here is DSP entry for release

!IF  "$(CFG)" == "minexe - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /Zp1 /W3 /GX- /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
# SUBTRACT CPP /Gy /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x419 /d "NDEBUG"
# ADD RSC /l 0x419 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /nologo /entry:"WinMainCRTStartup" /subsystem:windows /pdb:none /machine:I386 /nodefaultlib /ALIGN:16

!ELSEIF  "$(CFG)" == "minexe - Win32 Debug

you can replace your DSP entry for release by this.
also change this:
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
to :
DrawText(hdc, szHello, -1, &rt, DT_CENTER);

since strlen is Runtime function

Hi Miqel
it 1760 bytes mine is 16KB Oh!!!! 10 times.
plz, send ur code to me tkpramodkumar@yahoo.com
plz, send all the files.
thanx

send!
Hi Migel,
Thanx for ur valuable help.
At last it is working in Release version (I cahnged ALIGN:16 to ALIGN:0x1000).
but when I try first it shows following error.

--------------------Configuration: minexe - Win32 Release--------------------
Compiling...
minexe.cpp
Linking...
LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run
minexe.exe - 0 error(s), 1 warning(s)

When I run exe (u attached in zip file ) this is error
The c:\windows\desktop\minexe.exe file is improperly linked with alignment less than 0x1000.
Fix the error, and then link it again
Windows cannot run the program because it is in an invalid format.
The same error is showing when it run from IDE.

I changed /ALIGN:16 to /ALIGN:0x1000. then it poduced an exe with 3.50KB size. but it shows the same warning messages.

But the debug version can't runs
this is the error msg
--------------------Configuration: minexe - Win32 Debug--------------------
Linking...
minexe.obj : error LNK2001: unresolved external symbol __chkesp
Debug/minexe.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

minexe.exe - 2 error(s), 0 warning(s)
Hi migel
my first two question are not answered by any one.
I think u can help in that also
I am ready to give u all the points now , but can u help on that matters also. it will be a good help for me.
atleast the second one I think u can ?
Hi!
what OS you use?

I test my proj under Windows NT 4.0 SP6

--------------------Configuration: minexe - Win32 Debug--------------------
Linking...
minexe.obj : error LNK2001: unresolved external symbol __chkesp
Debug/minexe.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
it will not linked since __chkesp is the libarary defined method you can write stub for it  in the main module
void _chkesp(void)
{
}

about second Q see you later today :-)
I am using Win 98 and VC++6
Hi!
is release mode exe runs? (I can`t get it from yout comment)
Yeah, Realease mode runs and its size is only 3.5KB.
but debug mode had error
minexe.obj : error LNK2001: unresolved external symbol __chkesp
Debug/minexe.exe : fatal error LNK1120: 1 unresolved externals
again:>>
you can write stub for it  in the main
module
void _chkesp(void)
{
}
I am a beginner in this area
what is this stub ?? (just a function ? )
stub is the just empty function.
But why you want optimize DEBUG version? it is strange.
No i just informed u that debug version had some errors.
ok, what about my 2 & 1 question ?
abou 2.
you can have THE ONLY subclass procedure fora all controls in the dialog:
for example:
in your dialog class add next static members:

static ATOM     _g_atSubclassProp;
static LRESULT     CALLBACK SubclassProc(HWND hwnd, UINT uMsg, WPARAM wPar, LPARAM lPar);
in the dialog class constructor do this:
CMyDialog::CMyDialog()
{
     if (!_g_atSubclassProp)
          {
          _g_atSubclassProp = GlobalAddAtom("__subclassed__");
          }
}
in the WM_INITDIALOG (OnInitDialog) subclass all controls you want:
CMyDialog::OnInitDialog()
{
// subclass one edit for example:
  SubclassWnd(::GetDlgItem(m_hWnd, IDC_EDIT1), (FARPROC)SubclassProc);
}

// subclassing procedure
LRESULT     CALLBACK CMyDialog::ParentSubclassProc(HWND hwnd, UINT uMsg, WPARAM wPar, LPARAM lPar)
{
     WNDPROC wProc = (WNDPROC)GetProp(hwnd, (LPCSTR) MAKELONG(_g_atSubclassProp, 0));
     if (uMsg == WM_MOUSEMOVE)
          {
                        HWND hwndParent;
          LRESULT lres = CallWindowProc(wProc, hwnd, uMsg, wPar, lPar);
                        POINT pt;
                        GetCursorPos(&pt);
                        ::ScreenToClient(hwndParent, &pt;)
                        ::SendMessage(hwndParent, uMsg, wPar, MAKELPARAM(pt.x, pt.y));
          return lres;
          }
     if (uMsg == WM_DESTROY)
          {
          ::RemoveProp(hwnd, (LPCSTR)MAKELONG(_g_atSubclassProp, 0));
          ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wProc);
          }
     return CallWindowProc(wProc, hwnd, uMsg, wPar, lPar);
}

// helper method
BOOL CMyDialog::SubclassWnd(HWND hwnd, FARPROC lpfnProc)
{
     if (GetProp(hwnd, (LPCSTR)MAKELONG(_g_atSubclassProp, 0)))
          return TRUE; // already subclassed
     WNDPROC wndProc = (WNDPROC)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)lpfnProc);
     ::SetProp(hwnd, (LPCSTR)MAKELONG(_g_atSubclassProp, 0), (HANDLE)wndProc);
     return TRUE;
}



Hi miqel,
I will check ur code & comment latter.
thanx
Hi miqel,
I will check ur code & comment latter.
thanx
Hi miqel
it show some error when linking

MyDialogDlg.obj : error LNK2001: unresolved external symbol "protected: static unsigned short  CMyDialog::_g_atSubclassProp" (?_g_atSubclassProp@CMyDialog@@1GA)
Debug/MyDialog.exe : fatal error LNK1120: 1 unresolved externals
u not defined some fuctions in header file
so i changed that, any wrong ????
//header file
class CMyDialog : public CDialog
{

public:
     CMyDialog(CWnd* pParent = NULL);
     static LRESULT CALLBACK SubclassProc(HWND hwnd, UINT uMsg, WPARAM wPar, LPARAM lPar);
     BOOL SubclassWnd(HWND hwnd, FARPROC lpfnProc);
     
     //{{AFX_DATA(CMyDialog)
     enum { IDD = IDD_MYDIALOG_DIALOG };
     //}}AFX_DATA
     protected:
     virtual void DoDataExchange(CDataExchange* pDX);
     //}}AFX_VIRTUAL
protected:
     HICON m_hIcon;
     static ATOM _g_atSubclassProp;
     
     //{{AFX_MSG(CMyDialog)
     virtual BOOL OnInitDialog();
     afx_msg void OnPaint();
     afx_msg HCURSOR OnQueryDragIcon();
     //}}AFX_MSG
     DECLARE_MESSAGE_MAP()
};
//implementation file

CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
     : CDialog(CMyDialog::IDD, pParent)
{
     
     if (!_g_atSubclassProp)
         {
               _g_atSubclassProp = GlobalAddAtom("__subclassed__");
         }

     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
     
}
// subclassing procedure
LRESULT    CALLBACK CMyDialog::SubclassProc(HWND hwnd, UINT uMsg, WPARAM wPar, LPARAM lPar)
{
    WNDPROC wProc = (WNDPROC)GetProp(hwnd,(LPCSTR)MAKELONG(_g_atSubclassProp, 0));
     if (uMsg == WM_MOUSEMOVE)
         {
            HWND hwndParent = AfxGetMainWnd()->m_hWnd;
               LRESULT lres = CallWindowProc(wProc, hwnd, uMsg, wPar, lPar);
            POINT pt;
            GetCursorPos(&pt);
            ::ScreenToClient(hwndParent, &pt);
            ::SendMessage(hwndParent, uMsg, wPar, MAKELPARAM(pt.x, pt.y));
               return lres;
         }
    if (uMsg == WM_DESTROY)
         {
               ::RemoveProp(hwnd, (LPCSTR)MAKELONG(_g_atSubclassProp, 0));
               ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)wProc);
         }
    return CallWindowProc(wProc, hwnd, uMsg, wPar, lPar);
}

BOOL CMyDialog::SubclassWnd(HWND hwnd, FARPROC lpfnProc)
{
    if (GetProp(hwnd, (LPCSTR)MAKELONG(_g_atSubclassProp, 0)))
        return TRUE; // already subclassed
     

    WNDPROC wndProc = (WNDPROC)::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)lpfnProc);
     ::SetProp(hwnd, (LPCSTR)MAKELONG(_g_atSubclassProp, 0), (HANDLE)wndProc);
    return TRUE;
}


void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
     CDialog::DoDataExchange(pDX);
     
}

BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
     //{{AFX_MSG_MAP(CMyDialog)
     ON_WM_PAINT()
     ON_WM_QUERYDRAGICON()
     //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CMyDialog::OnInitDialog()
{
     CDialog::OnInitDialog();
     SubclassWnd(::GetDlgItem(m_hWnd, IDC_EDIT1), (FARPROC)SubclassProc);
     SetIcon(m_hIcon, TRUE);               // Set big icon
     SetIcon(m_hIcon, FALSE);          // Set small icon
     return TRUE;
}

void CMyDialog::OnPaint()
{
     if (IsIconic())
     {
          CPaintDC dc(this); // device context for painting
          SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
          int cxIcon = GetSystemMetrics(SM_CXICON);
          int cyIcon = GetSystemMetrics(SM_CYICON);
          CRect rect;
          GetClientRect(&rect);
          int x = (rect.Width() - cxIcon + 1) / 2;
          int y = (rect.Height() - cyIcon + 1) / 2;
          dc.DrawIcon(x, y, m_hIcon);
     }
     else
     {
          CDialog::OnPaint();
     }
}

HCURSOR CMyDialog::OnQueryDragIcon()
{
     return (HCURSOR) m_hIcon;
}
Hi!
you have to declare in the cpp file:
ATOM     CMyDialog::_g_atSubclassProp = NULL;
some words about header and method declaration:
I belive that you able resolve this little problem manually since EE window is not good editor.
Hi miqel,

u r going say something about header and method declarations ?
plz, tell me. what the difference, I am very much interested. all this informations are very valuable for me

i.e, u give answer for both 2 & 3
what about the #1 ?
plz, respond some thing to following link (my question about exe's size asked some time ago , no one responded )
I want to give all the points to u 4 ur valuable support

https://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=mfc&qid=20144848
Hi miqel,
if i ask some doubt about VC++ to u by mail (Ushakov@parus.com). Do u hesitate ???
Hi Miqel,
Thanx 4 ur valuable support.
Thanx again.
Hi!
you can ask me by EMail,
but preffered address is migel.geo@yahoo.com
Hi all,
end of a long discussion
thanx to all.