Hello guys.
I was recently messing out multiwaveview source, just to see what cool things could I add to my ROM.
It was very easy to notice, that we have there the method that makes lockscreen vibrate, on touch.
So let's stop talking and more modding.
Go to your source tree, and search for
frameworks/base/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
With search option (I use gedit, so CTRL+F), look for setVibrateEnabled.
There are plenty of options for removing vibration, the one I use, is setting a boolean to false on constructor method.
Code:
public MultiWaveView(Context context, AttributeSet attrs) {
super(context, attrs);
Resources res = context.getResources();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiWaveView);
mOuterRadius = a.getDimension(R.styleable.MultiWaveView_outerRadius, mOuterRadius);
mHorizontalOffset = a.getDimension(R.styleable.MultiWaveView_horizontalOffset,
mHorizontalOffset);
mVerticalOffset = a.getDimension(R.styleable.MultiWaveView_verticalOffset,
mVerticalOffset);
mHitRadius = a.getDimension(R.styleable.MultiWaveView_hitRadius, mHitRadius);
mSnapMargin = a.getDimension(R.styleable.MultiWaveView_snapMargin, mSnapMargin);
mVibrationDuration = a.getInt(R.styleable.MultiWaveView_vibrationDuration,
mVibrationDuration);
mFeedbackCount = a.getInt(R.styleable.MultiWaveView_feedbackCount,
mFeedbackCount);
mHandleDrawable = new TargetDrawable(res,
a.getDrawable(R.styleable.MultiWaveView_handleDrawable));
mTapRadius = mHandleDrawable.getWidth()/2;
mOuterRing = new TargetDrawable(res, a.getDrawable(R.styleable.MultiWaveView_waveDrawable));
// Read chevron animation drawables
final int chevrons[] = { R.styleable.MultiWaveView_leftChevronDrawable,
R.styleable.MultiWaveView_rightChevronDrawable,
R.styleable.MultiWaveView_topChevronDrawable,
R.styleable.MultiWaveView_bottomChevronDrawable
};
for (int chevron : chevrons) {
Drawable chevronDrawable = a.getDrawable(chevron);
for (int i = 0; i < mFeedbackCount; i++) {
mChevronDrawables.add(
chevronDrawable != null ? new TargetDrawable(res, chevronDrawable) : null);
}
}
// Read array of target drawables
TypedValue outValue = new TypedValue();
if (a.getValue(R.styleable.MultiWaveView_targetDrawables, outValue)) {
internalSetTargetResources(outValue.resourceId);
}
if (mTargetDrawables == null || mTargetDrawables.size() == 0) {
throw new IllegalStateException("Must specify at least one target drawable");
}
// Read array of target descriptions
if (a.getValue(R.styleable.MultiWaveView_targetDescriptions, outValue)) {
final int resourceId = outValue.resourceId;
if (resourceId == 0) {
throw new IllegalStateException("Must specify target descriptions");
}
setTargetDescriptionsResourceId(resourceId);
}
// Read array of direction descriptions
if (a.getValue(R.styleable.MultiWaveView_directionDescriptions, outValue)) {
final int resourceId = outValue.resourceId;
if (resourceId == 0) {
throw new IllegalStateException("Must specify direction descriptions");
}
setDirectionDescriptionsResourceId(resourceId);
}
a.recycle();
[COLOR="Red"][B]setVibrateEnabled(false);[/B][/COLOR]
}
But you can also set the method to always return null (or just deleting method and all it's usage, not recommended though if you want to come back some time)
Code:
public void setVibrateEnabled(boolean enabled) {
mVibrator = null;
}
Compile, and voilà, no more damn haptic feedback on lockscreen
TOO Hard for you ?, use ParanoidAndroid, and enjoy of this and some other mods, click my signature .
Which boolean gets called for haptic feedback in let's say trebuchet launcher or the gallery when you long press something like adding a widget on the homescreen because you're trying to move it to another home screen.
is there a difference between setHapticFeedbackEnabled and setVibrateEnabled?? Is it cooked into each and every individual apk or is there one giant key/string/boolean that controls everything?
Basically what I'm getting at is I'm just trying to find a way to disable all forms of haptic feedback. I've decompiled settings.apk, systemui.apk., framework-res.apk, framework.jar, and android policy.jar and have been forking around with that **** for the being learning some new stuff by editing different things here and there and seeing what it does. haha, very primitive but hey, I'm trying to learn everything I can!
Also, do I have to build the app from source to remove haptic feedback from it or can I decompile said apk, edit the certain xml/smali file recompile and voila?
Learning new **** is fun!
rdubyah said:
Which boolean gets called for haptic feedback in let's say trebuchet launcher or the gallery when you long press something like adding a widget on the homescreen because you're trying to move it to another home screen.
is there a difference between setHapticFeedbackEnabled and setVibrateEnabled?? Is it cooked into each and every individual apk or is there one giant key/string/boolean that controls everything?
Basically what I'm getting at is I'm just trying to find a way to disable all forms of haptic feedback. I've decompiled settings.apk, systemui.apk., framework-res.apk, framework.jar, and android policy.jar and have been forking around with that **** for the being learning some new stuff by editing different things here and there and seeing what it does. haha, very primitive but hey, I'm trying to learn everything I can!
Also, do I have to build the app from source to remove haptic feedback from it or can I decompile said apk, edit the certain xml/smali file recompile and voila?
Learning new **** is fun!
Click to expand...
Click to collapse
Each app handles haptic feedback on it's own, gallery, trebuchet, all of them, request for Context.VIBRATOR_SERVICE, wich is the main Service that manages the vibration (Obviously, framework is just the interface that "connects" user actions with kernel and then with hardware). For other side smali is not the best way to code android in general, but it's the same, so you could get the same results as editing java classes. Removing all forms of haptic feedback.. hm.. if i'm not bad, android loads device hardware through some framework service, not actually sure if it's VIBRATOR_SERVICE. So in theory, and pure theory, so dont believe me a word, you could trick android to make it think device doesn't have vibrator. Doing it manually on each app, would be SUCH a huge amount of work, so I definitively don't recommend it.
Good luck!
[MOD][SOURCE] Disable lockscreen vibration on any ROM
Heres another solution, your thread helped much:
http://forum.xda-developers.com/showthread.php?p=28227782
D4rKn3sSyS said:
Each app handles haptic feedback on it's own, gallery, trebuchet, all of them, request for Context.VIBRATOR_SERVICE, wich is the main Service that manages the vibration (Obviously, framework is just the interface that "connects" user actions with kernel and then with hardware). For other side smali is not the best way to code android in general, but it's the same, so you could get the same results as editing java classes. Removing all forms of haptic feedback.. hm.. if i'm not bad, android loads device hardware through some framework service, not actually sure if it's VIBRATOR_SERVICE. So in theory, and pure theory, so dont believe me a word, you could trick android to make it think device doesn't have vibrator. Doing it manually on each app, would be SUCH a huge amount of work, so I definitively don't recommend it.
Good luck!
Click to expand...
Click to collapse
I finally downloaded the CM9 source and compiled an unofficial.zip the other day and was amazing at how easy and simple it was removing haptic feedback from trebuchet launcher as well as the gallery. I can't believe how stupid I was trying to edit smali!
For trebuchet, DragController.java as well as for the gallery2 AlbumPage.java and AlbumSetPage.java solved so easily. VIBRATE_DURATION = 0 + mVibrator.vibrate(0); !!! I'm sure it's not the prettiest or cleanest way of removing vibration but hey, it works! Haha.
Related
Because the SenseSDK which is available at xda lacks a control for the HTC Slider I tried to create my own.
I finally fixed some bugs and changed a bit of the behavior and here is the first release version of my SenseSlider control.
The 2nd release is ready and stable. See Changelog for further info.
Features:
mimics HTC Slider
fully functional .net Control
does not depend on images for the bar background/slider thumb (drawn at runtime) and therefore allows different color-schemes
events for SelectedIndexChanged, StartedSliding, StoppedSliding, OnSliding (Gives thes index of the hovered icon)
supports vibration (aka haptic feedback)
includes a semi-transparent panel for overlay when sliding
does not depend on other control collections (SenseSDK only used for demo application; can be used with any other collection) (does not apply for new version, uses SmartDeviceFrameWork)
changes in the 2nd release:
uses the IImaging-Implementation of the SmartDevice-Framework and is now stable and more flexible (load the IImages with SDF in any way and add them to the slider)
supports an imagefile as slider thumb (see attached screenshot)
great speed improvement (fixed a bug which slowed drawing down)
made the source code of the demo application a lot more readable and understandable (or at least I hope so )
I uploaded a demo application to show some of the control's features. The source code for the demo is also available.
To use the Slider in your own applications just add the SenseSlider.dll and instantiate LunaticShade.SenseSlider (see the source of the demo application for details). (The new Version needs also the OpenNETCF Assemblies enclosed in the package or an installed version of the SmartDeviceFramework on the target device)
At this time the control cannot be drawn at designtime (due to heavy P/Invokes) but you can set the properties and events with the property editor.
Please report any bugs you may encounter.
If you got questions just ask
looks quite interesting. I will give it a try as soon as I can integrate in my apps (testing makes no sense - I also have HD2 )
keep on developing!
Obelix
Looks cool ! I'll try it as soon as a release is available !
Looks nice, not exactly like Sense (no vibration, no left-right/right-left gesture, if I tap&hold some icon and then swipe to left or right, the slider doesn't follow my finger), but good. Can't wait to be able to use it in my apps
first release,
see first post
That's VERY nice mate. I'm also particularly pleased that you used the Sense SDK interface in your demo, as I was considering using this slider in one of my apps that uses the Sense SDK heavily. I'm not considering it any more though - I'm all over it
I'm not currently at a dev machine and therefore can't really check out the control, so I do have one question that I may be able to answer if I looked in the IDE. Can you stop it changing page by sliding left and right on the page itself? I'd rather people had to use the slider to change page.
But yeah, very nice - thanks a lot!
I'm glad to hear that you like it.
johncmolyneux said:
Can you stop it changing page by sliding left and right on the page itself? I'd rather people had to use the slider to change page.
Click to expand...
Click to collapse
Actually it is the WinMo 6.5 TabControl which exposes this behavior. If you slide over a TabPage it changes the tab respectively, the senseslider then only reflects this action. So this is not the default behavior of the Slider (actually you could just set back the SelectedTab if it was not changed by the SenseSlider).
Ah fair enough. I didn't realise you'd used a tab control, but I guess that makes sense.
Thanks for the reply mate
nice control man.
i got 4-5 times a crash on the program. when i changed the button slider color, and stopped the vibration, then when i moved the slider fast from left to right, etc, an error occured.
overall nice work. i don't know if it is your icons, or the real time drawing, but the icons at the slider have a very bad quality. hope you can make the graphics much more similar to the HTC Slider looks
well done for a 0.1 version.
anyone knows what is wrong with this line?
Dim imageNames = assembly.GetManifestResourceNames().Where(Function(r) r.Contains("_b"))
i can't get the slider to work having a vb code. this slider needs so many things. i guess the reason that my slider is not working right now is because of the above code line, which returns me nothing, even though i have a picture which contains _b in the name
TeDeV said:
anyone knows what is wrong with this line?
Dim imageNames = assembly.GetManifestResourceNames().Where(Function(r) r.Contains("_b"))
i can't get the slider to work having a vb code. this slider needs so many things. i guess the reason that my slider is not working right now is because of the above code line, which returns me nothing, even though i have a picture which contains _b in the name
Click to expand...
Click to collapse
your resources have to be embedded. in the file browser of visual studio open the Resources folder (not the resx file!) select the images and in the property window change Build action to embed in resx.
i tried that, but when i add the image in the resources file, and choose the embed build action, i get errors
DividedByZeroException
stackTrace....
"σε LunaticShade.SenseSlider.Draw(Graphics g, Int32 x, Int32 y) σε LunaticShade.SenseSlider.Draw(Graphics g) σε LunaticShade.SenseSlider.OnPaint(PaintEventArgs e) σε System.Windows.Forms.Control.WnProc(WM wm, Int32 wParam, Int32 lParam) σε System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam) σε Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain) σε System.Windows.Forms.Application.Run(Form fm) σε PrimeKeys.Form1.Main() "
i also have a question.
how do you "connect" the senseSlider with the tabControl?
for example.... if i had two tabcontrols, how does the SenseSlider, knows which tabcontrol to bind?
i can't find that code in your sample.
TeDeV said:
i tried that, but when i add the image in the resources file, and choose the embed build action, i get errors
DividedByZeroException
stackTrace....
"σε LunaticShade.SenseSlider.Draw(Graphics g, Int32 x, Int32 y) σε LunaticShade.SenseSlider.Draw(Graphics g) σε LunaticShade.SenseSlider.OnPaint(PaintEventArgs e) σε System.Windows.Forms.Control.WnProc(WM wm, Int32 wParam, Int32 lParam) σε System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam) σε Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain) σε System.Windows.Forms.Application.Run(Form fm) σε PrimeKeys.Form1.Main() "
Click to expand...
Click to collapse
hm, that's strange. are you using pngs? did you set the IconSize Property of the senseslider? maybe a call of senseslider.updatevalues() in your constructor helps.
i also have a question.
how do you "connect" the senseSlider with the tabControl?
for example.... if i had two tabcontrols, how does the SenseSlider, knows which tabcontrol to bind?
i can't find that code in your sample.
Click to expand...
Click to collapse
actually the senseslider does not know that it controls a tabcontrol. It raises the event SelectedIndexChanged when the user selects an icon. In this event I activate the corresponding TabPage to be active.
yes but the corresponding tabpage of which tabcontrol?
if i have 2 tabcontrols, with 5-6 tabpages inside each tabcontrol, how does the slider knows, to which tabcontrol to bind? i don't get it.
i am creating the senseSlider dynamically. and this is my code...
senseSlider.Location = New System.Drawing.Point(0, 554) '504
'senseSlider.Dock = DockStyle.Bottom
senseSlider.Size = New System.Drawing.Size(480, 84)
senseSlider.BackColor = System.Drawing.Color.FromArgb(CInt(CByte((239))), CInt(CByte((235))), CInt(CByte((239))))
senseSlider.BorderBaseColor = System.Drawing.Color.FromArgb(CInt(CByte((235))), CInt(CByte((235))), CInt(CByte((235))))
senseSlider.DarkBaseColor = System.Drawing.Color.Silver
senseSlider.DarkSliderColor = System.Drawing.Color.FromArgb(CInt(CByte((35))), CInt(CByte((35))), CInt(CByte((35))))
senseSlider.HapticFeedback = True
senseSlider.IconSize = New System.Drawing.Size(72, 72) '56,56
senseSlider.IconSpacing = 25
senseSlider.LightSliderColor = System.Drawing.Color.Silver
senseSlider.UpdateValues()
'=====================
anything wrong there?
ok i have figured it out. it is the IconSize! if i use other png images with different dimensions than yours, then i get that error, no matter what. i don't get it. what is 56,56? because none of your icons are 56x56
yes but the corresponding tabpage of which tabcontrol?
if i have 2 tabcontrols, with 5-6 tabpages inside each tabcontrol, how does the slider knows, to which tabcontrol to bind? i don't get it.
Click to expand...
Click to collapse
The senseslider does not bind to a TabControl it only informs you that the SelectedIndex was changed. In the event handler for SelectedIndexChanged you decide what to do then. That is which TabControl to refresh. If you do nothing, nothing will happen. (In the sample I subscribed to the SelectedIndexChanged event and change the SelectedIndex of the TabControl to the SelectedIndex of the Slider by code).
ok i have figured it out. it is the IconSize! if i use other png images with different dimensions than yours, then i get that error, no matter what. i don't get it. what is 56,56? because none of your icons are 56x56
Click to expand...
Click to collapse
The IconSize only says how big the Icons are drawn. If they are smaller or bigger they will be stretched. I don't know why this does not work but
i will try to figure this out.
Very nice. I've been wanting to write something similar for an app that I want to write. You've just saved me a boatload of work! Thanx!
One issue that I saw though; when the app starts up, the ons screen keyboard icon is displayed over the slider. Opening and closing the keyboard hides the icon. Is there a way to have the application hide the keyboard icon on startup?
the slider must be able to DOCK = bottom.
if i have an app which rotates, then i can't use the height thing, in order to anchor.
and depending on the pda resolution the height will be different. and you have to consider that people want menu bar at the bottom, and not just the slider. so it is difficult to have this without dock = bottom.
thanks
TeDeV said:
the slider must be able to DOCK = bottom.
if i have an app which rotates, then i can't use the height thing, in order to anchor.
and depending on the pda resolution the height will be different. and you have to consider that people want menu bar at the bottom, and not just the slider. so it is difficult to have this without dock = bottom.
thanks
Click to expand...
Click to collapse
But that's a very simple thing to manually code, so not an issue. It would be good to not have to code it though, so docking would be nice.
Edit:
Actually, forget coding. Just anchor it in a panel that's docked to the bottom of your form.
cool. thx for you job.
Wow
Fantastic work - really looking forward to seeing this develop. It's so frustrating that HTC don't just release this stuff so that the developers here can make the phone shine compared to android and iphone - the standard winmo controls are so 1980s !
Cheers
Ian
I’m very new to programming, but I wanted to see if I can write a simple application that uses a dictionary API to query a server somewhere (if I said that right). I have some ideas for a few more difficult apps so I wanted to start with this simple one.
I’m mostly using Expression Blend to create these apps.
The first thing I would like to know is:
* How do I use a wp7 icon (from the icon pack) as a clickable button? I have an input search TextBox, but instead of using a simple button control (for the click event) I would like to use the magnifying glass icon as the search button --something similar to how Bing (on WP7) uses the mic in the search box. How can I accomplish this?
The second thing I would like to know is:
* How is an API use in app? I found a few APIs/ RSS feeds and XML data sources that I would like to utilize in my future apps, but I’m not sure how to implement them.
EXAMPLE: hxtp://api.somewebsite.xxx/xsomething=item1&sip=somethingelseI’ve read some about URI. What is this?
So basically, I would like to create an app that goes out to a server somewhere and fetch information based on a user’s keyword input and click event.
Please help!!!
- Learning developer
Welcome to silverlight programming
First up, here's a xaml snippet for showing an image in a button:
Code:
<Button Padding="4"
Margin="4">
<Image Source="Images/Search.png"/>
</Button>
I removed some of the attributes on the button and the image for clarity. Basically, a button can be used to show any UI element in this way.
Regarding your second question:
I haven't got a lot of experience outside of using WCF services, but for reading a feed I basically use a WebClient to download the xml file and then parse the file with linq:
Code:
WebClient client = new WebClient();
client.OpenReadAsync(new Uri([I]address[/I], UriKind.Absolute));
client.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
{
/* Error Processing */
}
else if (e.Cancelled)
{
/* Operation was cancelled */
}
else
{
XElement feed = XElement.Load(e.Result);
foreach (XElement item in feed.Descendants("item"))
{
/* Process here */
}
}
};
I'm open to suggestions for a better way to do this though...
Hi there,
I'm a little bit stuck with a page transition.
In my app, I select a name from a listbox which is located in another page (Page 2)
Once the name is selected from the listbox (in page 2) it automatically returns to the calling page.
Problem is that during the transition, in the OnNavigatedTo event of Page 1, it fires a query which takes some time and the transition is freezed during that time.
How can I add a ProgressBar to warn the user?
If possible, I'd like to stay as "official" as possible, so my idea is to use the standard ProgressBar supllied in the RTW.
I tried many searches and found nothing close to a workable sample on this.
Any help is much apprecitated in advance!
GFR_2009 said:
Hi there,
I'm a little bit stuck with a page transition.
In my app, I select a name from a listbox which is located in another page (Page 2)
Once the name is selected from the listbox (in page 2) it automatically returns to the calling page.
Problem is that during the transition, in the OnNavigatedTo event of Page 1, it fires a query which takes some time and the transition is freezed during that time.
How can I add a ProgressBar to warn the user?
If possible, I'd like to stay as "official" as possible, so my idea is to use the standard ProgressBar supllied in the RTW.
I tried many searches and found nothing close to a workable sample on this.
Any help is much apprecitated in advance!
Click to expand...
Click to collapse
If you're not already using the PerformanceProgressBar, you should be.
http://www.jeff.wilcox.name/2010/08/performanceprogressbar/
It's pretty much 'plug&play'.
There are 2 ideas which you could try to fix your problem.
An idea that you could try is using a DispatcherTimer. A timer will allow the function to finish loading, while creating an event which will fire to display the progress bar. When the page has finished loading, (say 1 sec) your timer could tick, and do whatever work you need done. Another solution would be to add a Loaded event on the page. This would allow you to run some code once the page is fully loaded. This is probably the best design. To do that, you'd need some code like this:
Code:
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ProgressBar pb = new ProgressBar();
pb.Style = PhoneApplicationService.Current.State["PerformanceProgressBar"] as Style;
pb.IsIndeterminate = true;
//add it onto the page, since it wasn't done in XAML.
LayoutRoot.Children.Add(pb);
}
Note that you can still create the ProgressBar in XAML, it was just easier to only show 1 file.
williammel,
Thanks a lot for the answer. Very clear and helpful!
Will try it right now.
Cheers,
Gus
Who can write Step by Step instruction by C++/VisualStudio 2008 ? for writing Hello World apps And simple actions of work with forms???
You can start here...http://www.hitmill.com/programming/cpp/helloWorld.htm
Remember a search engine is your friend.
Hope that I have help you.
In C++ you have the choice of WIN 32, ATL and MFC programming models. They are all different.
If you are using standard windows forms items ie buttons, editboxes, dropdowns etc. C# is a LOT easier.
stephj said:
If you are using standard windows forms items ie buttons, editboxes, dropdowns etc. C# is a LOT easier.
Click to expand...
Click to collapse
It is indeed much easier for "Hello World" type applications. For more complicated things, poor performance and lack of direct access to the native API begins to add up.
The original poster probably has some specific problem, the solution to which he hopes to find in a step-by-step tutorial. If he still has not been able to solve it, it might help to describe it to us.
O.K........
Over the next few posts, (Rome wasn't built in a day!), this will build into a step by step tutorial in how to create a basic WIN32 application. As a start we will use the C# .Net solution I wrote in reply to this post:
http://forum.xda-developers.com/showthread.php?t=1435629
The original request was for an application that calculates the check digit for an intermodal container number. For the uninitiated, intermodal containers are the ubiquitous 20ft and 40ft metal boxes that dominate the shipping industry.
All containers have an eleven digit serial number of the form:
ABCD 123456 7
Where ABC is the code for the container's owner, and D is the Category Identifier, almost always a 'U'. 123456 is the serial number of the box and the final number '7' is the checksum digit which is calculated from the previous 10 characters. When keying in container numbers into computer systems etc, it can be used to quickly check whether the container number is valid before further processing is done. The same thing applies to the last digit of your credit card number, it is calculated from the previous 15 numbers.
Container numbers conform to ISO6346 and more can be read here http://en.wikipedia.org/wiki/ISO_6346
We will build a WIN32 C++ Mobile 6 application to calculate the check digit from those given in a text box on the screen.
Validation will be minimal, if the user enters anything but characters of the form AAAA999999 in the textbox, nothing appears in the check digit box. When valid, the checkdigit magically appears.
You will need:- Visual Studio Professional 2008, not the express version, and an installed Windows Mobile 6.0 SDK
The Express version of VS cannot target mobile devices. VS 2003/5 can also be used, as well as earlier or later versions of the SDK, but you will encounter slight differences in VS or the SDK, that you will have to fight your way through yourself.
The finished application will look something like the attached image.
Under Win32, there is no drag and drop toolbox, all controls have to be created from scratch. All good fun, so roll up your sleeves, break out the birch twigs and let the self-flagellation begin.......
Right!.....Let's go............
From VS2008 select
File -> New -> Project
Select C++, Smart Device and Win32 Smart Device Project. Select the destination for the project and name it IS06346. See image 01.
Click OK
On the Platforms submenu of the next screen add the Windows Mobile 6.0 SDK to the project and remove the others. See image 02
........and, on the 'Application Settings' submenu, make sure the Windows Application radio button is on, and all others are off. See image 03
Click Finish. The VS wizard will create all the basic files we need under the directory given above.
In fact, pressing F5 should build this project and run it in the emulator. The application does very little at this stage, nothing to be precise, but it should work........... See 04
The main program is ISO3486.cpp This shell program is some 250 lines of code, most of it is needed for a "do nothing" program, but it boils down into five main functions.
WinMain() The entry point of the program, where the operating system will call it on initial load. Leave it alone.
InitInstance() Called immediately by WinMain and where the program creates its initial window etc. We will add a few bits of extra initialization here.
MyRegisterClass() Called by InitInstance to register the window class, just before the initial window is created. Leave it alone unless you really know what you are doing.
WndProc() The message processing loop for the main/parent window. Any windows event will be fired at this function as a Windows Message, it is up to us to process the ones we need. A few variables will go in here. All the original WM2003 "Hello World" program did, in the EVC based SDK, was to intercept the WM_PAINT message, find the client area of the screen, and draw the text "Hello World" in the middle of it.
About() The message processing loop for the About dialog box. We will be quite happy with the default action so we'll leave it alone.
To Do:
1.) Add reference to <string.h>
2.) Create two text boxes and display them. Limit the entry to 10 characters on the main edit box and disable input on the second check digit box.
3) Draw an "Enter container number:" text label above the edit boxes in response to the WM_PAINT message. The edit boxes will draw themselves when required.
4.) Intercept the EN_CHANGE message from the main edit box. If the length of the text in the box is 10 characters long, uppercase it, and if it is valid, generate the checksum and display it in the checksum box, otherwise clear the checksum box. Replace the textbox text with its uppercase value, but do not respond the the EN_CHANGE message generated by this change, as this will trigger an infinite shower of EN_CHANGE messages.
When this is done, we will have a working application.
To be continued.....................
Next...........
Let’s work our way down the TODO: list above.
1.) Add reference to “string.h”:
Later on we are going to use a call to towupper() to convert the input into uppercase. It is defined in string.h, so we have to add this to the source file.
At the top of the ISO6346.CPP after the line
Code:
#include "ISO6346.h"
Add the line:
Code:
#include "string.h"
2.) Create two text boxes and display them......
We will create two windows as text boxes, but we will save their handles as global variables as they are referenced from more than one function. While we are at it we also need a global Boolean variable to prevent the uppercased replacement from causing the runaway reaction mentioned above.
After:
Code:
HINSTANCE g_hInst; // current instance
HWND g_hWndMenuBar; // menu bar handle
Add:
Code:
HWND g_hWndText,g_hWndCheck;
bool g_Updating;
Now let’s create the text edit boxes. You may already know this, or this may be an eye opener, but all edit controls are actually windows in their own right, albeit that they are child windows of the main form.
In InitInstance() after:
Code:
if (!hWnd)
{
return FALSE;
}
add:
Code:
g_hWndText= CreateWindow(TEXT("EDIT"),NULL,WS_CHILD | WS_BORDER,40,50,110,20,hWnd,NULL,hInstance,NULL);
g_hWndCheck=CreateWindow(TEXT("EDIT"),NULL,WS_CHILD | WS_BORDER, 160,50,20,20,hWnd,NULL,hInstance,NULL);
This creates the text edit boxes. As yet they won’t be displayed, but we have to tweak them first. We want to disable the checkdigit box, so that the user cannot type anything into it as we will set it with the correct value when a valid container number is entered in the text box. We will disable it by calling the EnableWindow() function.
We also need to set the size of the text edit window to 10 characters. Under MFC and .NET this is a hoot, as it already a property of the edit control object, which has been conveniently wrappered for us, and we can just set that property. Here in the world of Win32, it is not quite so simple. We have to fire an EM_SETLIMITTEXT message at the window, to tell it that that is what we want. While we are at it, let's set the global g_Updating variable to be false, ready for use later, and here is as good a place as any to do it.
After the CreateWindow() lines we have just added, add the next three lines to do the above.
Code:
SendMessage(g_hWndText,EM_SETLIMITTEXT,10,0);
EnableWindow(g_hWndCheck,false);
g_Updating=false;
Now the windows exist as we want them, all we have to do is display them. At the bottom of the InitInstance() function after
Code:
ShowWindow(hWnd, nCmdShow);
add
Code:
ShowWindow(g_hWndText, nCmdShow);
ShowWindow(g_hWndCheck, nCmdShow);
The main window will now look after them and control them as required. Marvellous!
3) Draw an "Enter container number:" text label............
Now we need a label above the two boxes to tell the user to type a valid container number number into the text box. From the resource view of the project, open the String Table folder in ISO6346ppc.rc then open the String Table object. Click in the blank entry at the bottom and change the ID to IDS_ENTER and the Caption to "Enter container number:" Don't worry about the what the value is, if it is not '3', as the IDE will take care of it.
To get it drawn on the form, we will have to add it to the WM_PAINT event of the main window. We'll need a RECT structure to describe where we want the text to go, a buffer to store the string and while we are here let's add the function variables we are going to need later. At the top of the WndProc() function:
After:
Code:
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
add
Code:
TCHAR c,szBuffer[MAX_LOADSTRING];
RECT rt;
int i,j,k;
bool valid;
i,j and k are general variables for calculating the check digit. szBuffer is used to hold the "Enter container number:" string in WM_PAINT, and also for the contents of the edit box when it changes. As these two events will not occur at the same time, we can get away with it having a dual personality. Variable 'c' is used to read the string one character at a time and 'valid' is set to false if the the container number is not in the correct format.
Replace the TODO: line in the WM_PAINT handler
Code:
// TODO: Add any drawing code here...
with:
Code:
rt.top=20;
rt.bottom=40;
rt.left=40;
rt.right=180;
LoadString(g_hInst,IDS_ENTER,szBuffer,MAX_LOADSTRING);
DrawText(hdc,szBuffer,wcslen(szBuffer),&rt,0);
Now when the form is drawn, the label will appear in the right place.
4.) Intercept the EN_CHANGE message from the main edit box..........
There is no easy way to do the next bit step-by-step, so we will just do it, I'll explain later.........
Replace the standard code for the response to the WM_COMMAND message:
Code:
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
break;
case IDM_OK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
with this:
Code:
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDOK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
}
switch (wmEvent)
{
case EN_CHANGE:
if(g_hWndText == (HWND) lParam && !g_Updating)
{
GetWindowText(g_hWndText, szBuffer,MAX_LOADSTRING);
if(wcslen(szBuffer)==10)
{
k=0;
valid=true;
for(i=0; i<10; i++)
{
c=szBuffer[i]=towupper(szBuffer[i]);
if((i<4 && (c<'A' || c>'Z')) || (i>3 && (c<'0' || c>'9')))
valid = false;
j=int(c);
if (j > 64 && j < 91)
k += ((j - 55) + (j - 56) / 10) << i;
else
k += (j - 48) << i;
}
if(valid)
{
// Calculate final check digit
k = ((k % 11) % 10);
// Do not process the following update
g_Updating = true;
SetWindowText(g_hWndText,szBuffer);
g_Updating = false;
// Set check window to correct value
szBuffer[0]='0'+k;
szBuffer[1]='\0';
SetWindowText(g_hWndCheck,szBuffer);
// Position cursor at end of edit field.
SendMessage(g_hWndText,EM_SETSEL,10,10);
}
else
SetWindowText(g_hWndCheck,TEXT(""));
}
else
SetWindowText(g_hWndCheck,TEXT(""));
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
When the text edit box contents are changed, a EN_CHANGE message arrives at the parent window. It appears as a WM_COMMAND message with the wmEvent parameter containing the EN_CHANGE identifier, together with the handle of the window that generated the message. That is why the second 'switch' code exists to trap the EN_CHANGE event message.
If the EN_CHANGE message came from the Text edit window, not the Checksum window, then get the text within it. If the length is 10 characters long, then process the string. The variable k is used as a running total for the checksum. If after processing all 10 characters, the string is still valid, it is converted modulo 11 and then modulo 10 into the final checksum number. The checksum edit box is then updated with this value. The contents of the Edit box are replaced with its uppercase value. In doing so, we will cause another EN_CHANGE message to be sent to the parent window, which would cause this function to be executed again, and so on and so forth, causing an infinite shower of messages. To prevent this, we set the global variable g_Updating to true before making the change, and then setting it to false immediately afterwards. The test in the first line of the EN_CHANGE processing code, does not execute at all if g_Updating is true, thereby preventing this problem.
Build the final program, and test it in the emulator. Switch the build to 'Release' and the target to Windows Mobile Device, and run the executable on your device.
The complete ISO6346.cpp file is included in the attached zip file.
Here endeth the lesson...........
As a continuation, we will build the whole thing again from scratch, but next time using the Microsoft Foundation Class, MFC.
Watch this space..................
Don Reba said:
It is indeed much easier for "Hello World" type applications. For more complicated things, poor performance and lack of direct access to the native API begins to add up.
Click to expand...
Click to collapse
I totally agree with this! And worst thing is you can neither use a resource hacker tool nor a dependency walker tool, if you want to inspect a .NET CF application.
Using MFC......
From VS2008 as before select File->New->Project then select Visual C++, Smart Device, and MFC Smart Device Application.
Name it ISO6346 as before, and click OK. See image 01
On the platforms submenu select the Windows Mobile 6.0 SDK as before. See image 02
On the Application Type submenu, select the "Dialog Based" and "Use MFC in a static Library" radio buttons. See Image 03
By default the application comes with two dialog boxes for portrait and landscape but in our case this is complete overkill. We will get rid of the Landscape (Wide) dialog box.
In the Dialog folder of the resource view of ISO6346ppc.rc, delete the IDD_ISO6346_DIALOG_WIDE entry. See image 04.
To get this past the compiler, we will have to tidy it up a bit. In ISO6346Dlg.cpp delete the following sections of code.
Code:
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CISO6346Dlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
if (AfxIsDRAEnabled())
{
DRA::RelayoutDialog(
AfxGetResourceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_ISO6346_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_ISO6346_DIALOG));
}
}
#endif
and also:
Code:
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
Double Click in the IDD_ISO6346_DIALOG entry to open it up in the main window. Click on the "TODO: Place dialog controls here" label and change its caption to "Enter container number:", and position it near the top of the dialog box. From the Toolbox view, drop two edit controls on to the dialog box, under the above label. See image 05. Right click on the first box and select Add Variable. Name the first box edtText and click Finish. See image 06. Do the same for the second box and name it edtCheck. Notice that the wizard has added entries for the DoDataExchange(CDataExchange* pDX) function.
In OnInitDialog() after the line
Code:
// TODO: Add extra initialization here
Add:
Code:
Updating=false;
edtText.LimitText(10);
edtCheck.SetReadOnly();
Note that an Edit Control has more useful methods to call than the Win32 method above, where setting the text limit of the control has to be done by sending windows messages to it.
Right click on the Text Edit Box control and select "Add event handler..." select the EN_CHANGE message, take the default event handler function name, and click the "Add and Edit" button. See image 07 In ISO6346Dlg.h notice that the wizard has added the two edit boxes at the bottom of the file, and also added the message map thus:
Code:
public:
CEdit edtText;
CEdit edtCheck;
afx_msg void OnEnChangeEdit1();
In the //Implementation section of the same file after
Code:
HICON m_hIcon;
add:
Code:
bool Updating;
This will be used as before to prevent an infinite cascade of messages.
In the OnChangeEdit1() function add the following code:
Code:
int i,j,k;
wchar_t c;
bool valid;
CString strText,strCheck;
if(!Updating)
{
if(edtText.LineLength(0)==10)
{
edtText.GetLine(0,strText.GetBuffer(10),10);
strText.ReleaseBuffer(-1);
strText.MakeUpper();
k=0;
valid = true;
// Check the contents are of the form ABCD123456
for(i=0; i<10; i++)
{
c=strText.GetAt(i);
j=int(c);
if((i<4 && (c<'A' || c>'Z')) || (i>3 && (c<'0' || c>'9')))
valid = false;
if (j > 64 && j < 91)
k += ((j - 55) + (j - 56) / 10) << i;
else
k += (j - 48) << i;
}
if(valid)
{
// Calculate final check digit
k = ((k % 11) % 10);
strCheck.GetBufferSetLength(1);
strCheck.SetAt(0,'0'+k);
strCheck.ReleaseBuffer(-1);
edtCheck.SetWindowTextW(strCheck);
Updating = true;
// Do not process the following update
edtText.SetWindowTextW(strText);
Updating = false;
// Position cursor at end of edit field.
edtText.SetSel(10,10,0);
}
else //Invalid Not ABCD123456 - clear the check digit field
edtCheck.SetWindowTextW(TEXT(""));
}
else // Invalid - Not 10 char long - clear the check digit field
edtCheck.SetWindowTextW(TEXT(""));
}
This time we use CString objects to get/set the contents of the edit controls.
Right! That's it. Compile it and run it, either in the emulator or on the device.
See image 08. Notice that as this a dialog application, there are no menu buttons. When the [X] button is pressed the program terminates.
As another interesting point, compare the sizes of the two release executables. The Win32 version is around 8.5kb, that of the MFC version is around 167kb, both launch pretty damned quickly. Compare that with the . NET C# executable from the original post. That is around 9kb in size, but it takes your device around three seconds to shove it through the JiT compiler in order to able to run it, and that is for only a tiny .NET program.
Hi
I built a simple clock app yesterday. It was surprisingly easy. One question I have though is how to make my images smooth (without jaggies). I drew my clock face and hands in photoshop. At first I did them at 300x300 pixels and the jaggies were so obnoxious I threw those images away. Then I did everything at 1000 x 1000 pixels and resized down to 300 when I was finished. This was much better, but still not as smooth as the clock in Jelly Bean. I notice that most of the graphics and fonts I see in Android are all very smooth. I've been testing the app on a Galaxy Nexus.
What is the secret to creating/displaying nice smooth images?
Thanks, Derek
vector graphic is the keyword with fix sized effects (photoshop, ie. inner shadow is always 1px, above 256px use 2px)... yeah, the simple bitmap resizing won't give pro result for you
Heh Yeah, I've had this problem and it was a ***** to solve. Mainly because the answer is distributed over a dozen different posts on half a dozen different forums.
Anyway, the answer depends mainly on if you're using imageviews/buttons or something or if you're drawing directly to a/your own canvas. But the way to solve it can be applied to both. It basically involves using BitmapFactory.Options and configuring it correctly:
Code:
private BitmapFactory.Options ops;
ops = new BitmapFactory.Options();
ops.inPurgeable = true; //means the system can recycle and reclaim the memory used by the bmp when the system has low memory
ops.inDensity = 0; //load the bitmap without scaling it to the screen density
ops.inDither = false; //don't dither (you only want dithering when you're working/converting between bitmaps/canvasses with different color depths (16bit to 8 bit etc)
ops.inScaled = false; //no scaling, related to some other settings in ops
ops.inPreferredConfig = Bitmap.Config.ARGB_8888; //load the bmp into a 32bit argb bitmap
ops.inJustDecodeBounds = false; //if true, you're just looking at the underlying bmp data, eg to see the height/width without loading the bmp into memory
//then load your bitmap like so:
Bitmap yourbitmap = BitmapFactory.decodeResource(getResources(), R.drawable.yourprettybmp, ops);
Now you can use the bitmap to draw onto all kinds of surfaces or load it into widgets.
Be warned, this is a non-mutable bitmap. If you want to change it's data (like you want to draw on it by making it the backing bmp of a canvas) you'll have to get a copy of the BMPFactory.decodeResouce bit by adding
Code:
.copy(Config.ARGB_8888, true);
to it.
For resizing the bmp, you can also do the following (which returns a mutable bmp, so you won't need the copy bit above):
Code:
yourresizedbmp = Bitmap.createScaledBitmap(yourbmp, width, height, true);
Of course, you can combine all this in one step (where "res" is a reference to getResources()):
Code:
yourresizedbmp = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(res, bgIDInt, ops), width, height, true);
One more thing to ensure quick drawing, lower memory usage etc is to define the window type of your activity to match the colour depth of your bitmaps. You can do that by adding the following to the onCreate of your activity:
Code:
getWindow().setFormat(PixelFormat.RGBA_8888);
And if you're also drawing to a surface canvas in a thread, you also set that:
Code:
mSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
Anyway, the most important thing is the "ops" section. Hope you get it sorted!
PS: clean, minimal graphics can often be more easily gotten by just drawing things yourself on a canvas (extend the View object and override it's onDraw()). Just use a correctly setup and antialiased Paint to draw circles, lines and text on it and use the result.
Bitmaps are not generally used for graphics. Try to use PNG images, Google does so too.
I might be wrong, but from the OP it seems like you're using the same image size for all resolutions, use the Android Dpi Calculator to easily get the right dimensions for each screen resolution (and put the resized images respectively in /res/drawable-xhdi, hdpi, mdpi, ldpi...)
If you didn't do so, then it's definitely the problem as mdpi is the default behaviour of /res/drawable, so it will be awfully resized on your xhdpi Galaxy Nexus.
dealy663 said:
Hi
I built a simple clock app yesterday. It was surprisingly easy. One question I have though is how to make my images smooth (without jaggies). I drew my clock face and hands in photoshop. At first I did them at 300x300 pixels and the jaggies were so obnoxious I threw those images away. Then I did everything at 1000 x 1000 pixels and resized down to 300 when I was finished. This was much better, but still not as smooth as the clock in Jelly Bean. I notice that most of the graphics and fonts I see in Android are all very smooth. I've been testing the app on a Galaxy Nexus.
What is the secret to creating/displaying nice smooth images?
Thanks, Derek
Click to expand...
Click to collapse
Not sure if you've fixed this already but it's really easy. No code is required to remove jaggies, regardless of resolution. Assuming you're using Photoshop, choose save for web and devices, then select PNG-24 (not jpg or PNG-8) with transparency enabled. Initial resolutions of 200x200, 300x300 etc. are all fine; there's no need to create it at 1000x1000 and scale down if you need something smaller. Your graphics will look great.
One more tip - clock widgets fill a certain number of "squares" on the home screen grid, so just make sure that you determine the right number of dp pixels to cover the size you want (e.g., 2x2 or 2x4, or 3x3) and then specify it in xml. See the Android site for widget sizing.