Friday, June 19, 2009

How to Enable Tooltip for Dialog Controls

Lets get things straight. You want the user to be more dumb and want him/her to get an idea of what he wants to do with all the controls on his screen without reading the help file? Then dive right in. Else, Ciao. Have a good day.



Step 1: Enable the tooltip command using the command EnableToolTips (TRUE). Ideal location to include this line would be in your class' init routine CYourClass::InitDialog.

Step 2: Windows sends the tooltip related controls in TTN_NEEDTEXT message. We need to handle this. Add the following code to enable your handler in the MessageMap function

BEGIN_MESSAGE_MAP(CMyClassDlg, CDialog)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFF, OnToolTipNotify)
END_MESSAGE_MAP()


Step 3: Declare the handler function in your header.
afx_msg bool OnToolTipNotify( UINT id, NMHDR* pNMHDR, 
LRESULT* pResult );


Step 4: We are near. Just add then handler code in your cpp. Below is a sample of the same

bool CMyClassDlg::OnToolTipNotify( 
UINT id, NMHDR* pNMHDR, LRESULT* pResult )
{
// Get the tooltip structure.
TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;

// Actually the idFrom holds Control's handle.
UINT CtrlHandle = pNMHDR->idFrom;

// Check once again that the
// idFrom holds handle itself.
if (pTTT->uFlags & TTF_IDISHWND)
{
// Get the control's ID.
UINT nID = ::GetDlgCtrlID( HWND( CtrlHandle ));

// Now you have the ID. depends on control,
// set your tooltip message.
switch( nID )
{
case ID_BUTTON1:
// Set the tooltip text.
pTTT->lpszText = _T("First Button");
break;

case ID_EDIT1:
// Set the tooltip text.
pTTT->lpszText = _T("First Edit Box");
break;

default:
// Set the tooltip text.
pTTT->lpszText = _T("Tooltips everywhere!!!");
break;
}

return TRUE;
}

// Not handled.
return FALSE;
}

Friday, October 17, 2008

No Help inside VC IDE

I recently implemented the Help feature for an application. But, pressing F1 key or clicking on the corresponding button did not work out at all. No help window popped up. After much googling, I fell on this. This does not work when the application is run from inside the VC IDE. So, I went to the Debug directory and launched the application from there. Voila, help worked. But, still when pressing F1 key, I was getting an error message stating the the HLP file was missing. So, in order to disable that, the ON_WM_HELPINFO needed to be handled. Once that is done, the unwanted error message stops showing its ugly face.

Thursday, September 25, 2008

Adding accelerator keys in VC

A microsoft support link shows in a pretty straightforward way how to implement an accelrator key. Have a go

Getting the hyper link to work in CRichEditCtrl

Trying to get a mouse click to work in RichEdit and not succeeding? I faced a similar issue and ended up with this flow

Set the SetEventMask for your m_MyRichEdit (this is my control variable for the CRichEditCtrl class) to understand links
m_MyRichEdit.SetEventMask( \
m_MyRichEdit.GetEventMask() | ENM_MOUSEEVENTS)
Now, add a override function for OnNotify in your class. In the .h file, add
afx_msg BOOL OnNotify (WPARAM wParam, \
LPARAM lParam, LRESULT *pResult);
Add the corresponding function similar to the one below
BOOL CParentDlg:: OnNotify (WPARAM wParam, LPARAM lParam, LRESULT * pResult) 
{

if (LOWORD (wParam) == IDC_RICHEDIT)
{
MSGFILTER * mf = (MSGFILTER *) lParam;
switch (mf-> msg)
{
case WM_LBUTTONUP:
ENLINK *p_EnLink;
p_EnLink = (ENLINK *)lParam;
m_MyRichEdit.SetSel (p_EnLink->chrg);
CString szLinkString = m_RichEdit.GetSelText ();
break;
)
)

return CDialog:: OnNotify (wParam, lParam, pResult);
)
Now, your szLinkString will have the data you need to manipulate. You can use this with the ShellExecute function to popup whatever you want.

On, by the way, you need to add RTF content if you intend to make that identifiable. It goes something like
CString szT = "{\\rtf1 \\par http " + szAppendString + " \\par}";
My above code will popup a http link using which I Open it in ShellExecute

Tuesday, September 02, 2008

Auto Complete in VC++ 6

When the "Auto Complete" (Complete Word) feature of VC (6 in my case) stops working, all you need to do is
1. close the project
2. Go to the project directory
3. Remove the .ncb file in the directory
4. Re-open the project

Voila, its working !!!
(atleast it started working for me).

Ensoy

Wednesday, August 27, 2008

CTreeCtrl and Checkboxes

While working with CTreeCtrl with checkboxes, I came across these 2 issues

1. You would have set TVS_CHECKBOXES in the .rc file. Then during InitDialog, if
m_myTreeVar.SetCheck( hTreeWnd, TRUE)

is called, it will not work as expected. But, when the same line is called anywhere else later, it will work. To workaround this issue, the following two lines need to be added to simulate a removal/addition of the checkboxes flag at the beginning of InitDialog

m_myTree.ModifyStyle( TVS_CHECKBOXES, 0 );
m_myTree.ModifyStyle( 0, TVS_CHECKBOXES );

2. With the CTreeCtrl, when trying to get the handle of a "clicked" item using hittest, I fell on an issue that it was returning the handle of the NEXT item on the list and not the one which i clicked. The code is as below
 DWORD pos = GetMessagePos();
CPoint pt(LOWORD(pos), HIWORD(pos));
ScreenToClient(&pt);
UINT uFlags = 0;
HTREEITEM hItem = m_MainTree.HitTest(pt, &uFlags);


The above code returned the handle of the next list item from the one clicked. To fix the same, I just modified the "ScreenToClient" as below
m_myTree.ScreenToClient(&pt); 

and Voila!!! it worked!

Wednesday, May 28, 2008

Writing VB.Net app with c or C++ Dll

Added for my reconnaissance.

Step 1. Create a VC project (I used VC++ 6). An empty win32 DLL. The main things are below

Step 1a: For all the functions that needs to be exported, add "_stdcall" before their declaration and definition. For ex, I added
long _stdcall MyExportedFunction(int myinteger)

One VERY IMPORTANT thing to note. The return has to be something other than void as this causes an incompatibility between the DLL and the VB and the application will end up crashing.

Step 1b: Make sure to have a .def added to the VC project. The contents of my def file are


 MyVCLibrary.def : Declares the module parameters for the DLL.
LIBRARY "MyVCLibrary"
DESCRIPTION 'My VC Library DLL'

EXPORTS
; Explicit exports can go here
MyExportedFunction
My exported function prototype is
long _stdcall MyExportedFunction(int);

Now, thats it for the DLL. Compile and get it ready.

Step 2a: Create the VB.NET (I used Visual Studio 2008). In the Form Class, create a declaration as below (in a single line)


Declare Function MyExportedFunction Lib 
"MyVCLibrary.dll" (ByVal pcFilePath As Integer
) As Long

Step 2b: Call the function as below
Call MyExportedFunction(10)
. That's about pretty much to it.

Wednesday, April 09, 2008

Some Linux Tips

This is mainly from my experience in Red hat Linux 9.0 and Fedora Core (from as far back as 5 years). I have used the double quotes just to highlight the phrase to be typed on the command line. Remove the double quotes and type the commands.

How to check free space in my hard disk?

Typing "free" in your terminal command line lists out all the hard drives details.



"How do I find out the location of an executable file?

which <executable>" will show you the location from which it is called.



How can shutdown my machine with a command/shell script?

Create a shell script and put the following line in it (without the double quotes)

"shutdown -h now"

Executing this shell script shuts down your machine.



How do I mount a network shared folder in my LAN ?

For example sake, assume the network machine name is "nwsys" and the shared folder in that is "shared". Now create a directory to which you want to associate the shared folder to. Lets assume you create a folder "myshare" under "root" directory. Now the command will be

"smbmount //nwsys/shared /root/myshare -o username=<username>,workgroup=<workgroup>"

If all directories exist, you would be asked for the password, enter it. If no error message pops up, you are through.

From FC5, smbfs is removed and the command needs to modified to this:

mount -t cifs //nwsys/shared /root/myshare -o 
username=<myname>,workgroup=<myworkgroup>



I  had disconnected my LAN cable and reconnected it. Now, I am not able to connect to network machines through nautilius.

Close all nautilius windows and execute the following command at the command prompt

"killall nautilius"

This restarts the nautilius service and you should be able to connect to network systems.



 I created a shell script in windows and moved into linux. Here, i set all the requisite user rights for execution. When i tried to execute the script, it gives the error

bad interpreter: No such file or directory
The script seems to be syntatically fine.

This is a problem becaus of the difference in OSes. Open the script in vim and type the following command


:set ff=unix

This converts the script to unix based file format.