|
« |
March 2006 |
» |
|
S |
M |
T |
W |
T |
F |
S |
|
|
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
|
|
Programming Tips
Tuesday, 20 December 2005
To retrieve the machine name
Mood:
hungry
Topic: VC++
It is easy to get the name of a machine. Make sure your application supports "winsock"
WSADATA WSAData;
::ZeroMemory(&WSAData, sizeof(WSAData));
//init winsock
::WSAStartup(MAKEWORD(1,0), &WSAData);
Now get the host name:
char szHostName[MAX_PATH];
::gethostname(szHostName, MAX_PATH);
szHostName has got the host name
Now close winsock.
//close winsock
::WSACleanup();
Posted by Nibu babu thomas
at 1:33 PM
Updated: Tuesday, 20 December 2005 1:38 PM
Monday, 21 November 2005
Always on top dialogs and windows
Mood:
surprised
Topic: VC++
Ever wondered how to create an always on top dialog!
Here, take a look. :)
::SetWindowPos(m_hWnd /*Handle to the window*/,
HWND_TOPMOST /*Places the window at the top of the Z-Order*/,
0 /*New x*/,
0 /*New y*/,
0 /*New Width*/,
0 /*New Height*/,
SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE/*Flags*/
);
Now you might be wondering how to remove this feature. Just replace HWND_TOPMOST with HWND_NOTOPMOST
Happy days ahead.
Posted by Nibu babu thomas
at 2:08 PM
Updated: Monday, 21 November 2005 2:12 PM
Friday, 18 November 2005
A round dialog box!
Mood:
on fire
Topic: VC++
Ever wondered how those cute little round dialog boxes are created. I too wondered for some time.
But let me tell you it is easy.
So you don't trust me eh. Take a look:
//Create a region object globally.
CRgn m_EllipticRegion;
//a rect object
CRect crDialogRect;
//get your dialog size
this->GetClientRect(crDialogRect);
//Now create the elliptic region from the client rect
m_EllipticRegion.CreateEllipticRgn(0/*x*/,
0/*y*/,
crDialogRect.Width()/*width*/,
crDialogRect.Height() /*Height*/
);
//create a round dialog
this->SetWindowRgn(m_EllipticRegion, TRUE);
See I told you it's easy :)
Posted by Nibu babu thomas
at 5:30 PM
To move a captionless dialog.
Mood:
mischievious
Topic: VC++
Have you ever wondered how do people move dialogs by simply clicking anywhere inside the dialog and dragging them.
Have you ever wondered how captionless dialogs can be dragged arround.
If it is so then let me tell you that you can do the same with just one line of code.
Here goes the code:
void CNCHitTestProDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
//here is the code
SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
CDialog::OnLButtonDown(nFlags, point);
}
Posted by Nibu babu thomas
at 5:04 PM
Updated: Friday, 18 November 2005 5:07 PM
Tuesday, 15 November 2005
Drawing Boxes Around Characters and Strings
Mood:
chatty
Topic: Java
There are at least two ways to answer this question, and we'll look at both.
The Font class offers a getStringBounds() method that returns the bounding rectangle of a String.
The Graphics class offers a getFontMetrics() method that allows you to get the string width and character dimensions
for a finer level of detail.
Of course, there is also the option of just setting the border of a JLabel to draw the box for you. We'll look at all these here.
All three programs take a string from the command line to draw with a bounded box. If no string is provided, the word "Money"
is drawn, a word that offers a combination of uppercase and lowercase letters as well as a descender (the character "y,"
which extends below the baseline).
1. Using Font.getStringBounds()
The first way to draw a bounding box is sufficient for most cases in which you are explicitly drawing the characters. Given the
graphics context passed into your paintComponent() method, get its font rendering context, which contains internal details
about the font, and then ask that what the bounding rectangle is for your message. Then, draw the rectangle.
String message = ...;
Graphics2D g2d = (Graphics2D)g;
FontRenderContext frc = g2d.getFontRenderContext();
Shape shape = theFont.getStringBounds(message, frc);
g2d.draw(shape);
Just be sure to coordinate the location of the drawn string with the rectangle, as demonstrated by the following program:
import javax.swing.*;
import java.awt.*;
import java.awt.font.*;
public class Bounds {
static class BoxedLabel extends JComponent {
Font theFont = new Font("Serif", Font.PLAIN, 100);
String message;
BoxedLabel(String message) {
this.message = message;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Insets insets = getInsets();
g.translate(insets.left, insets.top);
int baseline = 150;
g.setFont(theFont);
FontMetrics fm = g.getFontMetrics();
// Center line
int width = getWidth() - insets.right;
int stringWidth = fm.stringWidth(message);
int x = (width - stringWidth)/2;
g.drawString(message, x, baseline);
Graphics2D g2d = (Graphics2D)g;
FontRenderContext frc = g2d.getFontRenderContext();
Shape shape = theFont.getStringBounds(message, frc);
g.translate(x, baseline);
g2d.draw(shape);
g.translate(-x, -baseline);
g.translate(-insets.left, -insets.top);
}
}
public static void main(String args[]) {
final String message;
if (args.length == 0) {
message = "Money";
} else {
message = args[0];
}
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Bounds");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent comp = new BoxedLabel(message);
frame.add(comp, BorderLayout.CENTER);
frame.setSize(400, 250);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
2. Using Graphics.getFontMetrics()
The second mechanism demonstrates a finer level of detail that may or may not be necessary. What if you want to draw a box
around each character of a string? With a proportional font, each character is a different width, so you can't just calculate font
size multiplied by number of characters to get the width of the whole string. Instead, you work with the FontMetrics class to get
the metrics of each character involved.
g.setFont(theFont);
FontMetrics fm = g.getFontMetrics();
Some information you get is specific to the font, and not at the character level. When you draw a string, you specify the
baseline -- the line where the bottom of the character is to be drawn. The space above the line for the tallest character,
including diacritical marks like umlauts, is called the ascent. Below the line for descenders (such as the letter "y") is called
descent. Space reserved for between lines of characters is called leading, pronounced like the metal,
not like taking charge of a group. The height is the sum of these three.
int ascent = fm.getAscent();
int descent = fm.getDescent();
int leading = fm.getLeading();
int height = fm.getHeight();
There are also values for the maximum of the three sizes, though this may be the same as the non-max value.
int maxAdv = fm.getMaxAdvance();
int maxAsc = fm.getMaxAscent();
int maxDes = fm.getMaxDescent();
As far as width goes, you can ask for the width of the whole string:
int stringWidth = fm.stringWidth(message);
So, in the case of the bounding box of a string, you'd take its width and height to create the rectangle.
int stringWidth = fm.stringWidth(message);
int height = fm.getHeight();
To work at the character level, the FontMetrics class has a charWidth() method.
By looping through your string, you can increase the x coordinate of your box drawing to draw the next box.
charX += fm.charWidth(message.charAt(i));
The following program demonstrates the use of both sets of methods to box off the whole string and each character.
import javax.swing.*;
import java.awt.*;
public class Metrics {
static class BoxedLabel extends JComponent {
Font theFont = new Font("Serif", Font.PLAIN, 100);
String message;
BoxedLabel(String message) {
this.message = message;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Insets insets = getInsets();
g.translate(insets.left, insets.top);
int baseline = 150;
g.setFont(theFont);
FontMetrics fm = g.getFontMetrics();
int ascent = fm.getAscent();
int descent = fm.getDescent();
int height = fm.getHeight();
int leading = fm.getLeading();
int maxAdv = fm.getMaxAdvance();
int maxAsc = fm.getMaxAscent();
int maxDes = fm.getMaxDescent();
// Center line
int width = getWidth() - insets.right;
int stringWidth = fm.stringWidth(message);
int x = (width - stringWidth)/2;
g.drawString(message, x, baseline);
drawHLine(g, x, stringWidth, baseline);
drawHLine(g, x, stringWidth, baseline-ascent);
drawHLine(g, x, stringWidth, baseline-maxAsc);
drawHLine(g, x, stringWidth, baseline+descent);
drawHLine(g, x, stringWidth, baseline+maxDes);
drawHLine(g, x, stringWidth, baseline+maxDes+leading);
int charX = x;
for (int i=0; i <= message.length(); i++) {
drawVLine(g, charX, baseline-ascent, baseline+maxDes+leading);
if (i != message.length()) {
charX += fm.charWidth(message.charAt(i));
}
}
}
void drawHLine(Graphics g, int x, int width, int y) {
g.drawLine(x, y, x+width, y);
}
void drawVLine(Graphics g, int x, int y, int height) {
g.drawLine(x, y, x, height);
}
}
public static void main(String args[]) {
final String message;
if (args.length == 0) {
message = "Money";
} else {
message = args[0];
}
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Metrics");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent comp = new BoxedLabel(message);
frame.add(comp, BorderLayout.CENTER);
frame.setSize(400, 250);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
One thing to mention about this program is that had the font been italic, the character might not have been bound to within
the drawn box. If you need absolute control over the bounds of a string, consider looking at the TextLayout class, which
allows you to get the outline shape of a string for further manipulation.
3. Setting Border of JLabel
The JLabel class has a setBorder() method. This allows you to directly "add" the bounding box without having to subclass to
draw it yourself. The system classes will calculate the appropriate location for you, as the following example shows.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
public class Bordered {
public static void main(String args[]) {
final String message;
if (args.length == 0) {
message = "Money";
} else {
message = args[0];
}
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Border");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent comp = new JLabel(message, JLabel.CENTER);
comp.setFont(new Font("Serif", Font.PLAIN, 100));
comp.setBorder(LineBorder.createBlackLineBorder());
frame.getContentPane().setLayout(new GridBagLayout());
frame.add(comp);
frame.setSize(400, 250);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
Happy days ahead...:)
Posted by Nibu babu thomas
at 12:37 PM
Updated: Tuesday, 15 November 2005 12:51 PM
Repainting immediately!
Mood:
bright
Topic: VC++
Many times it happens that when we call Invalidate(TRUE /*or FALSE*/) the window is not refreshed immediately.
It happens because Invalidate() simply marks an area to be repainted.
The area will be painted only during the next WM_PAINT message. This message won't be immediately fired
if there is another blocking event taking place. Now you should be knowing why it didn't repaint immediately.
:)
So now what to do if we wish to refresh the window immediately.
Simply do this!
Invalidate(TRUE);//marks the window to be painted
UpdateWindow();//by passes the message queue and paints immediately
Don't forget to call Invalidate() before UpdateWindow() or else the window will not be refreshed.
The reason being that your region is not marked to be refreshed.
Posted by Nibu babu thomas
at 12:02 PM
Updated: Tuesday, 15 November 2005 12:07 PM
Monday, 14 November 2005
To retrieve the ID of any window.
Mood:
sharp
Topic: VC++
This is how we can retrieve the ID of any window.
LONG lWndID = ::GetWindowLong(this->m_hWnd, GWL_ID);
Simple!
Posted by Nibu babu thomas
at 5:01 PM
Window style modification at runtime
Mood:
sharp
Topic: VC++
Here is how you can change the style of any control of at runtime. Here we are modifying the style of a top level window like a
dialog or a frame window to display a maximize button if there is not one already.
LONG lCurStyle = GetWindowLong(this->m_hWnd, GWL_STYLE);
SetWindowLong(this->m_hWnd,
GWL_STYLE,
lCurStyle|WS_MAXIMIZEBOX, SWP_FRAMECHANGED);
The second argument in SetWindowLong and GetWindowLong gives the index of the activity that the functions has to deal with.
Here GWL_STYLE specifies that the functions have to deal with the style index.
For further details take a look in the MSDN documentation
Posted by Nibu babu thomas
at 4:24 PM
Updated: Monday, 21 November 2005 1:59 PM
Thursday, 10 November 2005
Screen resolution
Mood:
incredulous
Topic: VC++
We can get the screen resolution as follows:
int xScreenRes = ::GetSystemMetrics(SM_CXSCREEN);
int yScreenRes = ::GetSystemMetrics(SM_CYSCREEN);
Yeah you have it!
Posted by Nibu babu thomas
at 4:42 PM
Updated: Thursday, 10 November 2005 4:43 PM
How to get the height and width of a bitmap?
Mood:
energetic
Topic: VC++
It's real easy to retrieve the height and width of a bitmap. Trust me, take a look.
CBitmap cbBmp;
cbBmp.LoadBitmap(IDB_BITMAPID);
BITMAP bmpInfo;
//clear bmpInfo
ZeroMemory(&bmpInfo, sizeof(bmpInfo));
cbBmp.GetBitmap(&bmpInfo);
There is another way of going about this. Take a look:
CBitmap cbBmp;
cbBmp.LoadBitmap(IDB_BITMAPID);
BITMAP bmpInfo;
//clear bmpInfo
ZeroMemory(&bmpInfo, sizeof(bmpInfo));
cbBmp.GetObject(sizeof(bmpInfo), &bmpInfo)
//now get the height and width...
int bmpHeight = bmpInfo.bmHeight;
int bmpWidth = bmpInfo.bmWidth;
See I told you it's easy.
Posted by Nibu babu thomas
at 3:48 PM
Updated: Thursday, 10 November 2005 4:48 PM
Quick way of changing background color of edit controls
Mood:
cheeky
Topic: VC++
Windows provides us a way to override the look and feel of a component at runtime throught this method.
For more information take a look at the MSDN documenation on
OnCtlColor().
The nCtlColor parameter contains the category of the control being painted, for eg:
CTLCOLOR_BTN -- Button control
CTLCOLOR_DLG -- Dialog box
CTLCOLOR_EDIT -- Edit control
CTLCOLOR_LISTBOX -- List-box control
CTLCOLOR_MSGBOX -- Message box
CTLCOLOR_SCROLLBAR -- Scroll-bar control
CTLCOLOR_STATIC -- Static control
Well if you want to check for the painting of a particular control then use
pWnd->GetDlgCtrlID(), which returns the id of the control being painted.
The device of the context of the control being painted is in the pointer pDC.
This is how we go about it:
HBRUSH CTestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
//call base class implementation first otherwise it may undo what we have done.
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
//Get the ctrl id and check whether we are painting the edit control or not.
if (pWnd->GetDlgCtrlID() == IDC_OF_EDITBOX)
{
// Set the text color to red.
pDC->SetTextColor(RGB(255, 0, 0));
//set to trasparent mode
pDC->SetBkMode(TRANSPARENT);
//unless we do this there won't be any effect.
hbr = m_brush;
}
return hbr;
}
Posted by Nibu babu thomas
at 11:05 AM
Updated: Thursday, 10 November 2005 4:47 PM
Tuesday, 8 November 2005
How to register a Hotkey for your application?
Mood:
sharp
Topic: VC++
Now what's a Hotkey. An easy definition would be a key that remains hot throughout the lifetime of an
application. Whenever you press the hotkey it does it's work no matter where the focus is where the
input is directed to, etc.
So here's how we go about it.
//Make this a member variable of your class.
UINT uniqueIdentifier;
//creates a unique identifier for your hotkey so that there is no hotkey id clashes
uniqueIdentifier = ::GlobalAddAtom("Somename");
::RegisterHotKey(
m_hWnd/*Your window handle*/,
uniqueIdentifier/*Unique identifier to uniquely identify this hotkey*/,
MOD_ALT|MOD_CONTROL /*Modifier keys*/,
VK_F10/*Virtual key code of any key*/
);
//Add these message map entries
BEGIN_MESSAGE_MAP(..., ...)
ON_MESSAGE(WM_HOTKEY, HotKeyHandler)
ON_WM_DESTROY()
END_MESSAGE_MAP()
//toggle visibility
LRESULT CYourDialog::HotKeyHandler(WPARAM wParam, LPARAM lParam)
{
static BOOL visible = IsWindowVisible();
if(visible)
ShowWindow(SW_HIDE);
else
ShowWindow(SW_SHOWNORMAL);
visible = !visible;
}
void CYourDialog::OnDestroy()
{
//if you register you will have to unregister too.
UnregisterHotKey(m_hWnd, uniqueIdentifier);
}
Yeah this is how we go about it.
A cleaner approach would be create a wrapper class around this hotkey. So that registration and
unregistration can take place smoothly.
Posted by Nibu babu thomas
at 5:28 PM
Updated: Thursday, 10 November 2005 4:46 PM
How to know the state of a key?
Mood:
energetic
Topic: VC++
During a function call if you want to determine the state of a key use
::GetAsyncKeyState(VK_SHIFT)
Wait a minute there is one more:
::GetKeyState(VK_SHIFT)
This function retrieves the status of the
specified virtual key. The status specifies whether
the key is up, down, or toggled (on, off?alternating
each time the key is pressed)
To retrieve state information for all the virtual keys, use
::GetKeyboardState(PBYTE lpKeyState)
lpKeyState: Pointer to the 256-byte array that receives the status data for each virtual key.
Posted by Nibu babu thomas
at 3:56 PM
Updated: Thursday, 10 November 2005 4:44 PM
Loading images on the fly
Mood:
cool
Topic: VC++
Anywhere any time. Happy programming.
HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle()/*application instance handle*/,
"C:\\Nibu.bmp"/*file name*/,
IMAGE_BITMAP/*or IMAGE_ICON, IMAGE_CURSOR*/,
0/*original width*/,
0/*original height*/,
LR_LOADFROMFILE
);
//create bitmap object
CBitmap *bmp = CBitmap::FromHandle(hBmp);
//That's it. Very easy ;)
Posted by Nibu babu thomas
at 1:43 PM
Updated: Thursday, 10 November 2005 4:44 PM
Newer | Latest | Older
|
|