I'm currently doing some programs myself with the free MS embedded VC++.. and I'm finding it comfortable to do a simple dialog-based programs for PPC. I think I can have most of the background code going, and I've just got the GUI .. alright.
Now the question, how do I do a copy/paste to/from clipboard? I had most of the stuff done using the included MFC Wizard. I can get and send data to/from an EditBox (TextBox, whatever you call it). However, the click-hold thing on PPC doesn't seems to work on my EditBox, and hence I'm thinking what's needed to enable a simple Copy/Paste on an EditBox.
Currently, I'm using the simple
Code:
m_editBox = _T("the message I want to show");
UpdateData(FALSE); //send it to the EditBox
Any guide from here would be appreciated. However, I'm thinking there may not be an easy way to do that, hence I've also tried adding a 'Copy' and 'Paste' button to do the job, but I've tried things like
Code:
SetClipboardData(x, x)
GetClipboardData(x)
None works.
I have also tried
Code:
COleDataObject DataObject;
and with the handle etc etc .. but I can't seems to find this COleDataObject , is that in some other environment (e.g. not PPC env)?
Help
Fast solution:
http://www.pocketpcdn.com/articles/sip.html
(this shows/hides sip on get/lost focus in edit controls and add the context menu too)
and this is a simple example how to copy datas into clipboard
if(OpenClipboard(NULL))
{
EmptyClipboard();
HLOCAL clipbuffer = LocalAlloc(0, 100);
wcscpy((WCHAR*) clipbuffer, (WCHAR*) (vtNumber.bstrVal));
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
free(szMsg);
LocalFree(clipbuffer);
}
I hope this help u
bye
Thanks for your respond.. things work.. a bit
Code:
//put a test char
char *test;
test = (char*) malloc(100);
strcpy(test, "blah blah blah");
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
HLOCAL clipbuffer = LocalAlloc(0, 100);
wcscpy((WCHAR*) clipbuffer, (WCHAR*) test);
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//free(szMsg); //not sure what 'szMsg' is
LocalFree(clipbuffer);
}
Things somewhat works. I'm not really sure which part I've got wrong. I'm suspecting some memory allocation is giving me problems. The thing is, if I were to use 'CF_UNICODETEXT' on the 'SetClipboardData(x,x)' line, I get something to paste on other programs (PPC Notes). BUT, the thing pasted is some funny stuff (e.g. letters that cannot be rendered, hence I get the little squares). If I were to use 'CF_TEXT', I don't seems to able to send my stuff to the clipboard or it made it invalid for (PPC Notes) pasting (e.g. I'm not able to paste it in PPC Notes).
Thanks.
BTW, if you are in the mood, can you give me a Paste function as well. Thanks a bunch.
Hi hanmin.
Odd I didn't notice this thread sooner.
Any way if you still having problems with this code here is the solution:
You are working with char and strcpy so your text is in ASCII (each letter one byte).
But you are calling SetClipboardData with CF_UNICODETEXT so it expects WCHAR (UNICODE) where each letter is two bytes.
The strange letters are the result of two consecutive bytes being interpreted as a single letter (probably lends you in Chinese or Japanese region of the Unicode table)
Windows mobile doesn't usually work with ASCII so the text you get from the edit box will already be in Unicode and won't give you any trouble.
The code should look like this:
Code:
//put a test char
CString test; //since you are working with MFC save your self the trouble of memory allocation
test = L"The text I want on clipboard"; //The L makes the string Unicode
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
//not sure why you need to copy it again, but here goes:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
wcscpy((WCHAR*) clipbuffer, (WCHAR*)(LPCTSTR)test); //LPCTSTR is an overloaded operator for CString
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//szMsg probably belongs to some larger application and is irrelevant
LocalFree(clipbuffer);
}
I never used the clipboard APIs my self so I can't guide you farther but this code should work.
Hope this helps.
Wooo hooo.. Thanks levenum. I'm back on business!
You code works wonderfully.. just the final code "LocalFree(clipbuffer);" seems to cause problems. Without that, it works. I'm not sure if it will cause a memory leak.. but that's not much of my concern now
Now my Paste also works, and it seems that the magic code is the "LPCTSTR", which I have NO idea what it is (I'm more of a pure C person and.. a Java person ) Thanks again.
Glad I could help.
I am working from Ubuntu right know (Linux distro in case you didn't know) so I do not have access to my off-line MSDN files, but I recommend you check out the documentation for SetClipboardData.
It is possible it releases the memory it self so when you call LocalFree the handle is no longer valid.
That could also be the reason why you need to allocate memory instead of passing it the string directly.
As for LPCTSTR it is simple and not C++ related:
#define const* WCHAR LPCTSTR
Its M$ way of saying Long Pointer to Constant STRing
T changes meaning based on what you are working with:
If you work with ASCII TCHAR is char
If you work with Unicode TCHAR is WCHAR
Basically these are just all redefinitions of variable types so you can distinguish what they are used for.
In C++ you can overload operators. For example you can have a function which changes the way ++ works with certain types of variables.
In our case CString class has a function which determines what happens when you try to cast (convert) it to a pointer to string.
Thats all the "magi" code.
Good luck with your app.
Small update:
Since I had to go in to XP anyway (to change PDAMobiz ROM which kept hanging at random and didn't let me use BT to latest PDAViet which for now seem very good) I took a quick peek at the help files.
Here is why you should not release the memory:
After SetClipboardData is called, the system owns the object identified by the hMem parameter. The application can read the data, but must not free the handle or leave it locked. If the hMem parameter identifies a memory object, the object must have been allocated using the LocalAlloc function
Click to expand...
Click to collapse
levenum, thanks. You've got me almost there. There are several stuff I need to polish up though. Attach is a pre-mature version of what I wanted to do. There are several issues (including the fact that, only the 4 characters of the password are effectively used, which can be easily fix, I think. Just need to find the bug and squash it) that I like to polish up. They are sorted in order of importance (to me):
[1] Keyboard (SIP) pop up.
For this, I digged around and got to know that the function
"SHSipPreference( HWND, SIP_UP)" is the one to used. However, it never did what it suppose to do. I have had it put inside the "OnSetfocusConfirmPasswordEdit()" of the edit box, which should be called when it is set focus. I suspect that is I haven't set the HWND correctly. I have tried "NULL" and also tried using the "CWnd* pParent" from my dialog constructor (generated code my MFC Wizard). None of them worked.
[2] Editbox focusing.
For some reason, the focus on my main-dialog is correct on the editbox of the 'message'. However, on the dialog which is to confirm the password (which I called using
Code:
CConfirmPasswordDlg confirmPasswordDlg;
int nResponse = confirmPasswordDlg.DoModal();
is focusing on the 'Ok' button. What I like it to do is to focus on the 'confirmPasswordEdit' box, and it ought to automatically pop up the keyboard (SIP).
[3]Reduced size pop up dialog
I was trying to make the 2nd confirm password dialog smaller, something like a pop up in the PPC rather than something that take up the whole screen without much contents in it. How would you go about doing that? Is it not possible in PPC? E.g, if you were to use Total Commander, and start copying files around, they do have a pop up that does take up the entire screen. I'm suspecting I shouldn't do a "confirmPasswordDlg.DoModal()", and should some what do something myself. I have tried, SetVisible(1) thing, but that doesn't work. Or it shouldn't meant to work because my 1st screen is a dialog screen?
[4]Timer?
I would like to have a function of which after a certain period of idle time, it will clear off the clipboard and close itself. How would I go about doing this? Some sort of background thread thing?
Anyone can shine a light on my issues above? On MS-embedded Visual C++ (free), with Pocket PC 2003 SDK (free)
Attached the Blender-XXTea edition
Works on PPC2005 and WM5 (should work on WM6)
Does not require .NET framework
VERY small (54K)
hanmin said:
[2] Editbox focusing.
For some reason, the focus on my main-dialog is correct on the editbox of the 'message'. However, on the dialog which is to confirm the password (which I called using
Code:
CConfirmPasswordDlg confirmPasswordDlg;
int nResponse = confirmPasswordDlg.DoModal();
is focusing on the 'Ok' button. What I like it to do is to focus on the 'confirmPasswordEdit' box, and it ought to automatically pop up the keyboard (SIP).
Click to expand...
Click to collapse
In your CConfirmPasswordDlg::OnInitDialog handler, call GetDlgItem(confirmPasswordEdit).SetFocus() and return FALSE. That should handle the focus and possibly the SIP popup.
3waygeek said:
In your CConfirmPasswordDlg::OnInitDialog handler, call GetDlgItem(confirmPasswordEdit).SetFocus() and return FALSE. That should handle the focus and possibly the SIP popup.
Click to expand...
Click to collapse
HEY! The focus works! The working code is
Code:
((CWnd*) CConfirmPasswordDlg::GetDlgItem(IDC_CONFIRM_PASSWORD_EDIT))->SetFocus();
BTW, I'm wondering, whats the effect of a return TRUE/FALSE on a 'OnInitDialog()'?
Anyway, the keyboard pop up is still not working. I'm using the command
Code:
void CConfirmPasswordDlg::OnSetfocusConfirmPasswordEdit() {
SHSipPreference( (HWND)g_pParent, SIP_UP);//
}
which I suspect the 'g_pParent' is NULL. If it is NULL, would it work?
Ok, I haven't used MFC for a while and almost not at all on PPC but I will give this a shot:
1) MFC forces dialogs to be full-screen. Here is a detailed explanation on how to change that. Note that for some reason this will work only once if you use the same variable (object) to create the dialog several times.
If you use a local variable in say a button handler thats not a problem because the object is destroyed when you exit the function.
2) There is a simple SetTimer API. You can give it a window handle and then add an OnTimer message handler to that window. Or you could give it a separate function which will be called (say TimerProc). In that case you can give it NULL as window handle.
Note that CWnd objects have a member function with the same name (SetTimer) which sets the timer with that window handle (so that window will receive WM_TIMER message). If you want the raw API call ::SetTimer.
Also note that the timer will continue to send messages / call your special function every x milliseconds until you call KillTimer.
3) I am not sure what the problem with the SIP is. CWnd and derived classes like CDialog have a function called GetSafeHwnd (or GetSafeHandle, I don't remember exact name). Try passing that to SHSipPreference.
If that does not work here is an article with an alternate solution.
WOHO!! Everything works NOW!!.. MUAHAHHAHA.. wait til you see my release version
Non maximized windows works using the code suggested at the page. Although I still do not understand where the heck this '.m_bFullScreen' property came from. It is not anywhere obvious to be seen.
Code:
CNfsDlg dlg;
dlg.m_bFullScreen = FALSE;
dlg.DoModal();
Timer works using the
Code:
xx{
//your code...
CBlenderDlg::SetTimer(1, 5000, 0); //event 1, 5 seconds, something
//your code...
}
void CBlenderDlg::OnTimer(UINT nIDEvent){
//do something here for the timer
}
although somehow, the OnTimer() only works if I went to the MFC class wizard to add the WM_TIMER function. Doesn't work when I add in the OnTimer() myself. Must be something else that I've missed. Anyway.
Keyboard issue solved using
Code:
SHSipPreference( CBlenderDlg::GetSafeHwnd(), SIP_UP);
Glad its working out for you.
Couple of comments:
1) Somewhere at the top of the cpp file, if I am not mistaking there is something called a message map. It's a bunch of macros that lets MFC know what window messages it handles. An entry there is what was missing when you added the function manually.
2) m_bFullScreen is just another among many undocumented features. M$ likes to keep developers in the dark. For instance WM 2003 and up have an API called SHLoadImage which can load bmp, gif, jpg and some other formats and return HBITMAP which all the usual GDI functions use.
This API was undocumented until WM 5 came out and even then they said it only works for gif...
hanmin said:
BTW, I'm wondering, whats the effect of a return TRUE/FALSE on a 'OnInitDialog()'?
Click to expand...
Click to collapse
The return value indicates whether or not the standard dialog handler (which calls your OnInitDialog) should handle setting the focus. As a rule, OnInitDialog should return TRUE, unless you change the focus within the handler (or you're doing an OCX property page on big Windows).
I haven't done much WinMob/CE development -- I've been doing big Windows for 15+ years, so window message handling is pretty much second nature. I started doing Windows development back in the days when you didn't have C++ or MFC boilerplate; you had to implement your own DialogProc, crack the messages yourself, etc. It's a lot easier now.
CommandBar / MenuBar
I'm back.. with more questions
Not much of a major issue, but rather an annoying thing I've found. Probably that's what evc/mfc/m$ intended to do that.
Anyway, I'm starting my way of getting around CommandBar. I created a MFC skeleton, studied the code, and that's what I've found, after I've created a CommandBar/MenuBar on evc and putting it in
Code:
if(!m_mainMenuBar.Create(this) ||
!m_mainMenuBar.InsertMenuBar(IDR_MAINMENUBAR) ||
!m_mainMenuBar.AddAdornments() ||
!m_mainMenuBar.LoadToolBar(IDR_MAINMENUBAR))
{
TRACE0("Failed to create IDR_MAINMENUBAR\n");
return -1; // fail to create
}
where I have the variable 'CCeCommandBar m_mainMenuBar' and I have created a MenuBar on evc with the Id 'IDR_MAINMENUBAR'. The menu bar works flawlessly on my dialog based application, when I have the 1st level as a pop up. Example
MenuBar --> 'File' --> 'New', 'Save'
Where 'File' is a folder-like thing that pop-ups and show the contents (i.e. in this example, 'New', and 'Save'). However, given the SAME code to load the CommandBar/MenuBar, it will not work, if I were to put the actual command at 1st level. Example, this will not work
MenuBar -> 'New', 'Save'
where there isn't any folder-like pop-up to store the commands 'New', and 'Save'.
I know that I can have buttons for these commands, and probably works. But, what I'm trying to do is to utilize the bottom-left-right softkey in WM5/6. If I were to have the 'File'->'New','Save' structure, it works fine with WM5, showing it as a softkey. But, if I were to do just 'New','Save' it will not show up in both WM2003 emulator and WM5.
As a matter of fact, even if I have (say) File->New,Load, and I added a new command (i.e. not folder-like-pop-up), example 'Help' on the CommandBar/MenuBar, the File->New,Load will not show up too. It seems like the 1st level command (ie. without a folder-pop-up), causes some problems and stop it from loading further.
Guys, ring any bell?
two bytes more
levenum said:
Hi hanmin.
Odd I didn't notice this thread sooner.
Any way if you still having problems with this code here is the solution:
You are working with char and strcpy so your text is in ASCII (each letter one byte).
But you are calling SetClipboardData with CF_UNICODETEXT so it expects WCHAR (UNICODE) where each letter is two bytes.
The strange letters are the result of two consecutive bytes being interpreted as a single letter (probably lends you in Chinese or Japanese region of the Unicode table)
Windows mobile doesn't usually work with ASCII so the text you get from the edit box will already be in Unicode and won't give you any trouble.
The code should look like this:
Code:
//put a test char
CString test; //since you are working with MFC save your self the trouble of memory allocation
test = L"The text I want on clipboard"; //The L makes the string Unicode
//codes you've given
if(OpenClipboard()) //OpenClipboard(NULL) gives me error
{
EmptyClipboard();
//not sure why you need to copy it again, but here goes:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
wcscpy((WCHAR*) clipbuffer, (WCHAR*)(LPCTSTR)test); //LPCTSTR is an overloaded operator for CString
SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard();
//szMsg probably belongs to some larger application and is irrelevant
LocalFree(clipbuffer);
}
I never used the clipboard APIs my self so I can't guide you farther but this code should work.
Hope this helps.
Click to expand...
Click to collapse
I know it is a bit late! But there is a mistake the code snippet:
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2); //remember: every letter 2 bytes long!
needs to be
HLOCAL clipbuffer = LocalAlloc(0, test.GetLength() * 2+2);
the terminating 0 is als 2 bytes long!
Those errors are sometimes fatal, with very less chance to find them!
ms64o
Hey Guys!
I need a little help in Sql Database programming in vb.net!
how can i Connect to 2 Databases and Join their queries?
Code:
Dim SQLcon As SqlCeConnection = Nothing
Dim strPDAPfad As String = AppDir & "\Catalogs\" & Config.QuestionFileName
Const strPDAPasswort As String = ""
SQLcon = New SqlCeConnection("Data Source=" & strPDAPfad & ";" & strPDAPasswort)
SQLcon.Open()
Dim SQLString As String = "SELECT * FROM QUESTIONS WHERE ID = '" & QuestionID & "'"
Dim SQLQuery As SqlCeCommand = New SqlCeCommand(SQLString, SQLcon)
i want to join 2 databases so i can order one table with the help of another!
Just Like I would have one Database with 2 Tables
"SELECT Questions.ID FROM Questions ORDER BY Stats.Wrong DESC"
I think this is not possible to to it directly. You might need to load the data of one into a temp table in the other db and then do the query.
Would be bad I need to do this very often
I will try to find out how to attach both files to an SQL Compact server and try that again
[edit] found nothing!
scilor said:
Hey Guys!
I need a little help in Sql Database programming in vb.net!
how can i Connect to 2 Databases and Join their queries?
Code:
Dim SQLcon As SqlCeConnection = Nothing
Dim strPDAPfad As String = AppDir & "\Catalogs\" & Config.QuestionFileName
Const strPDAPasswort As String = ""
SQLcon = New SqlCeConnection("Data Source=" & strPDAPfad & ";" & strPDAPasswort)
SQLcon.Open()
Dim SQLString As String = "SELECT * FROM QUESTIONS WHERE ID = '" & QuestionID & "'"
Dim SQLQuery As SqlCeCommand = New SqlCeCommand(SQLString, SQLcon)
i want to join 2 databases so i can order one table with the help of another!
Just Like I would have one Database with 2 Tables
"SELECT Questions.ID FROM Questions ORDER BY Stats.Wrong DESC"
Click to expand...
Click to collapse
Dim SQLString As String = "SELECT * FROM tbl1, tbl2 WHERE tbl1.ID = tbl2.ID and tbl1.QuestionID = '" & QuestionID & "'"
Thank you But I want to do this out of 2 Databases not out of 2 Tables!
I have not actually had the need to do so.
But I would check out LINQ, I have a feeling it should be able to do that.
I'll check it for you when I get home (at work at the moment).
LINQ how it works? I only find rare information for it!
how can I use it in VB.net 2008 ?
There is SQL Command named
UNION
which can Combined Identical Structure Database to Combine the Record from Both Table have you tried it
But how can I use that practically, i know in php is that easily because I know the alias of the Database but with my technic
New SqlCeCommand(SQLString, SQLcon)
there only can be one Database Per Connection
LINQ will read all the records from both databases into memory then do the merge join and give you the matched resultset. You could probably do it much better yourself. If you are going to repeat this join often, then for the sake of the user's patience, you should at least try to do it yourself.
If one table is known to be smaller (in KB) than the other, then I would cache that table in a Dictionary<keyColumn, DataRow> construct. Then I would open a data reader on the second table and process each of those rows by referring to the cached version of the first table.
Of course, I assume you have already ruled out the possibility of permanently merging the two databases? That would be the best solution. But perhaps there are two separate applications, to which you do not have the source code, responsible for maintaining these two databases, in which case I fully understand.
I need to Seperate both!
It is for my Driving Licence Trainer. and I want to Seperate Training Files from the Statistics
If one table is known to be smaller (in KB) than the other, then I would cache that table in a Dictionary<keyColumn, DataRow> construct. Then I would open a data reader on the second table and process each of those rows by referring to the cached version of the first table.
Click to expand...
Click to collapse
@ftruter Could you make an Example for using it for sorting?
Hi,
I try to make a widget for gmail in order to have the number of unread messages in my gmail box (the only existing app I found is not free and for a such basic feature, that's a shame!). To manage it, I thought about using the GmailProvider package, especially the android.provider.Gmail.LabelCursor class, you can find its documentation here.
I use dynamic loading because I don't have the source code so I can't do a regular import statement (see here).
But I can't manage loading the class in my application, always get an ClassNotFoundException...
Code:
final String apkFile = "/system/app/Gmail.apk:/system/app/GmailProvider.apk";
[...]
dalvik.system.PathClassLoader clsLoader =
new dalvik.system.PathClassLoader(apkFile,ClassLoader.getSystemClassLoader());
Class<?> gmailProviderHandler =
Class.forName("android.provider.Gmail.LabelCursor", true, clsLoader);
Method m = gmailProviderHandler.getDeclaredMethod("getNumConversations", (Class[])null);
int nbConv = ((Integer)m.invoke(gmailProviderHandler, (Object[])null)).intValue();
Any idea ?
An other solution would be to use the atom feed, but using this package seems nicer to me.
Alternatively, is there a way I can get the source of this package, maybe the class name has changed since the javadoc (not official) has been written ???
Thanks,
LTourist
It's me again...
Nobody can help me ?
On my side, I've made some progress : I finally get some classes from the package. I did a dexdump on the package in xml, and it seems that the classes names do not match the ones in the package... That's kind of strange...
But now, I'm facing another problem... Whatever I do, I'm facing a NullException when I'm calling gmailProviderHandler.NewInstance((Class[]) null), and just for information, gmailProviderHandler seems to be not null, as an equals(null) is false...
Any idea from where this could be coming from ???