|
When I scroll down a DataGrid, then select a row in the DataGrid, then rebind the DataGrid, the DataGrid displays the rows starting with the very first row, DataGrid.Row = 0.
How do I reposition the DataGrid to display the row that was last selected?
The DataGrid is bound to a Command in the DataEnvironment.
I have tried the following code in the DataGrid.SelChange event, using the BookMarks property, where lastRow is declared as a Variant:
DataGrid1.Col = 0
lastRow = DataGrid1.Text
i = DataGrid1.Row
DataGrid1.Bookmark(i) = lastRow
When I run the code I get an error on the last line: "Run-time error '13': Type mismatch"
Any ideas? Thanks.
|
|
|
|
|
Member 9819470 wrote: DataGrid1.Bookmark(i) = lastRow I don't know what type "Bookmark(i)" is expecting, but it won't be a string.
VB6 is deprecated, and no longer supported.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Hi
A customer of asked us to build him a multi-language based support VB6 scraper, for which we had the need to detect UTF-8 based encoded strings to decode it later for proper displaying in application UI. It's necessary to point out that this need arises based on VB6 limitations to natively support UTF-8 in its controls, contrary to what it happens in .NET where you can tell a control that it should expect UTF-8 encoding. VB6 natively supports ISO 8859-1 and/or Windows-1252 encodings only, for which textboxes, dropdowns, listview controls, others can't be defined to natively support/expect UTF-8 as you can do in .NET considering what we just explained; so we would see weird symbols such as é, è among others, making it a whole mess at the time of displaying.
So, next function contains whole UTF-8 encoded punctuation marks and symbols from languages like Spanish, Italian, German, Portuguese, French and others, based on an excellent UTF-8 based list we got from this link - Ref. http://home.telfort.nl/~t876506/utf8tbl.html
Basically, the function compares if each and one of the listed UTF-8 encoded sentences, separated by | (pipe) are found in our passed string making a substring search first. Whether it's not found, it makes an alternative ASCII value based search to get a match. Say, a string like "Societé" (Society in english) would return FALSE through calling isUTF8("Societé") while it would return TRUE when calling isUTF8("SocietÈ") since È is the UTF-8 encoded representation of é.
Once you got it TRUE or FALSE, you can decode the string through DecodeUTF8() function for properly displaying it, a function we found somewhere else time ago and also included in this post.
[code]
Function isUTF8(ByVal ptstr As String)
Dim tUTFencoded As String
Dim tUTFencodedaux
Dim tUTFencodedASCII As String
Dim ptstrASCII As String
Dim iaux, iaux2 As Integer
Dim ffound As Boolean
ffound = False
ptstrASCII = ""
For iaux = 1 To Len(ptstr)
ptstrASCII = ptstrASCII & Asc(Mid(ptstr, iaux, 1)) & "|"
Next
tUTFencoded = "Ä|Ã…|Ç|É|Ñ|Ö|ÃŒ|á|Ã|â|ä|ã|Ã¥|ç|é|è|ê|ë|Ã|ì|î|ï|ñ|ó|ò|ô|ö|õ|ú|ù|û|ü|â€|°|¢|£|§|•|¶|ß|®|©|â„¢|´|¨|â‰|Æ|Ø|∞|±|≤|≥|Â¥|µ|∂|∑|âˆ|Ï€|∫|ª|º|Ω|æ|ø|¿|¡|¬|√|Æ’|≈|∆|«|»|…|Â|À|Ã|Õ|Å’|Å“|–|—|“|â€|‘|’|÷|â—Š|ÿ|Ÿ|â„|€|‹|›|ï¬|fl|‡|·|‚|„|‰|Â|Ú|Ã|Ë|È|Ã|ÃŽ|Ã|ÃŒ|Ó|Ô||Ã’|Ú|Û|Ù|ı|ˆ|Ëœ|¯|˘|Ë™|Ëš|¸|Ë|Ë›|ˇ" & _
"Å|Å¡|¦|²|³|¹|¼|½|¾|Ã|×|Ã|Þ|ð|ý|þ" & _
"â‰|∞|≤|≥|∂|∑|âˆ|Ï€|∫|Ω|√|≈|∆|â—Š|â„|ï¬|fl||ı|˘|Ë™|Ëš|Ë|Ë›|ˇ"
tUTFencodedaux = Split(tUTFencoded, "|")
If UBound(tUTFencodedaux) > 0 Then
iaux = 0
Do While Not ffound And Not iaux > UBound(tUTFencodedaux)
If InStr(1, ptstr, tUTFencodedaux(iaux), vbTextCompare) > 0 Then
ffound = True
End If
If Not ffound Then
'ASCII numeric search
tUTFencodedASCII = ""
For iaux2 = 1 To Len(tUTFencodedaux(iaux))
'gets ASCII numeric sequence
tUTFencodedASCII = tUTFencodedASCII & Asc(Mid(tUTFencodedaux(iaux), iaux2, 1)) & "|"
Next
'tUTFencodedASCII = Left(tUTFencodedASCII, Len(tUTFencodedASCII) - 1)
'compares numeric sequences
If InStr(1, ptstrASCII, tUTFencodedASCII) > 0 Then
ffound = True
End If
End If
iaux = iaux + 1
Loop
End If
isUTF8 = ffound
End Function
Function DecodeUTF8(s)
Dim i
Dim c
Dim n
s = s & " "
i = 1
Do While i <= Len(s)
c = Asc(Mid(s, i, 1))
If c And &H80 Then
n = 1
Do While i + n < Len(s)
If (Asc(Mid(s, i + n, 1)) And &HC0) <> &H80 Then
Exit Do
End If
n = n + 1
Loop
If n = 2 And ((c And &HE0) = &HC0) Then
c = Asc(Mid(s, i + 1, 1)) + &H40 * (c And &H1)
Else
c = 191
End If
s = Left(s, i - 1) + Chr(c) + Mid(s, i + n)
End If
i = i + 1
Loop
DecodeUTF8 = s
End Function
[/code]
Hope it helps
Regards
Diego Sendra
e-mail: contact@diegosendra.com
http://www.diegosendra.com
*Please note you have to download the function from http://www.diegosendra.com/samples/code/VB6/VB6_isUTF8.txt considering some of the UTF encoded symbols in tUTFencoded variable were lost/deleted at the time of copy/pasting the code into this thread
-- modified 24-Jun-13 20:18pm.
|
|
|
|
|
This forum is for asking questions - hence the big red button labelled "Ask a Question". Your post looks more like it should be a tip/trick[^].
Also, posting your email address in a public forum is a great way to have your inbox flooded with spam.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi Richard, maybe we didn't know there was such a tip/tricks section?
|
|
|
|
|
There is an Articles section, where you can submit articles and tips.
Roy.
|
|
|
|
|
Great, I've posted it there now. Didn't know such a section existed in the site
-- modified 24-Jun-13 17:24pm.
|
|
|
|
|
diegosendra wrote: Didn't know such a section existed in the site Strange then that you managed to submit this Tip[^] successfully there, last October!
Use the best guess
|
|
|
|
|
Hi ...
I have a problem to address the stapler of a HP9000 printer. I need a single print job, but the SDK i use produces individual jobs for each format that i use.
I'm already stopped the que with System.Printing, then read the que and trie to get the stream of each job and copy theme into a single job.
Unfortunately, the stream is not readable.
Private Sub CombineJobsInPrintQue(ByVal Printer As String)
Try
Dim serverName As String = Printer.Remove(Printer.LastIndexOf("\"))
Dim printerName As String = Printer.Remove(0, Printer.LastIndexOf("\") + 1)
Dim ps As New PrintServer(serverName, PrintSystemDesiredAccess.AdministrateServer)
Dim queue As New PrintQueue(ps, printerName, PrintSystemDesiredAccess.AdministratePrinter)
Dim Jobs As PrintJobInfoCollection = queue.GetPrintJobInfoCollection
Dim Job As PrintSystemJobInfo
Dim s As PrintSystemJobInfo = queue.AddJob("NewJob")
Dim myStreamWrite As System.IO.Stream = s.JobStream
Dim x As Integer = 0
For Each Job In Jobs
Try
Job.Refresh()
Dim myStreamRead As System.IO.Stream = Job.JobStream
Dim buffer(Job.JobSize) As Byte
myStreamRead.Read(buffer, 0, Job.JobSize)
myStreamWrite.Write(buffer, x, Job.JobSize)
x += Job.JobSize
Job.Cancel()
Catch ex As Exception
ERRlog("CopyJob", ex)
End Try
Next
myStreamWrite.Close()
Catch e As Exception
ERRlog("CombineJobsInPrintQue", e)
End Try
End Sub
Job.JobStream == nothing!
Apparently I can not merge the jobs this way ...
Now I have considered whether there is any other way to combine the jobs from the Que. But reading from the SPL file and then write to the Que does not work, the SPL-File is EMF coded and the data are not in RAW format. The job is generated but always ignored when printing.
Private Sub CombineJobsTest(ByVal Printer As String)
Try
Dim serverName As String = Printer.Remove(Printer.LastIndexOf("\"))
Dim printerName As String = Printer.Remove(0, Printer.LastIndexOf("\") + 1)
Dim ps As New PrintServer(serverName, PrintSystemDesiredAccess.AdministrateServer)
Dim queue As New PrintQueue(ps, printerName, PrintSystemDesiredAccess.AdministratePrinter)
Dim Jobs As PrintJobInfoCollection = queue.GetPrintJobInfoCollection
Dim Job As PrintSystemJobInfo
Dim MyNewJob As PrintSystemJobInfo = queue.AddJob("Neu")
Dim myStreamWrite As System.IO.Stream = MyNewJob.JobStream
Dim myStreamRead As System.IO.Stream = New IO.FileStream("D:\Share\Temp\FP00119.SPL", IO.FileMode.Open)
Dim myStreamRead2 As System.IO.Stream = New IO.FileStream("D:\Share\Temp\FP00120.SPL", IO.FileMode.Open)
Dim length As Integer = myStreamRead.Length + myStreamRead2.Length
Dim buffer(Job.JobSize) As Byte
myStreamRead.Read(buffer, 0, myStreamRead.Length)
myStreamRead2.Read(buffer, myStreamRead.Length, myStreamRead2.Length)
myStreamWrite.Write(buffer, 0, length)
myStreamWrite.Close()
Catch e As Exception
ERRlog("CombineJobsTest", e)
End Try
End Sub
I'm still considering whether you can possibly tell the HP9000 in PCL6 !COLLECT ALL JOBS and then !STAPLE ALL JOBS ... but unfortunately I have not found this anywhere.
Somehow it must be possible to combine the jobs ... I hope someone here has a good idea ...
Thanks and regards
|
|
|
|
|
tolarion wrote: Somehow it must be possible to combine the jobs
I wouldn't expect it to be possible. Think of it this way. Open a command prompt and type COPY WordDoc1.docx + WordDoc2.docx WordDoc.docx , then try and open the WordDoc.docs file. It's not going to work because each doc has it's own header, formatting tables, tail details, checksums, ... which are now no longer valid.
You'd have to read the job streams, interpret the contents of all the jobs, create a new job, reformat the data from all of the jobs you want to combine into a single job with all the data ini the correct places. For example, you can't have the headers from each job spread throughout the target job. The data for each must be combined into a header that is at the beginning of the job and reformatted so that it makes sense.
Oh, and you'd have to put in the details to tell the printer to staple in the correct place and orientation, because I'm guessing that you didn't tell each job to staple.
In short, doing this is a HUGE undertaking.
|
|
|
|
|
The EMF Files are not the same as the WordDoc i think ... it's a kind of Vector Format for each page with BeginPage / EndPage BeginDoc / EndDoc ... so i try to do exactly what you described with the spooling ... and open it with a EMF viewer (Articles/10586/EMF-Printer-Spool-File-Viewer) ... and it worked. The information on page etc are unfortunately lost ... but i give it a hope that it is not so HUGE undertaking as you mid think ?!
Perhaps i need is some kind of EMF reformatting ... getting each single page out of the spool file. Stacking theme again and writing all to the new spool or just print it again ...
The stapling is done by the printer driver ...
But my problem is still: how to get the right spooling filename ! Can not read it from PrintSystemJobInfo ?!
|
|
|
|
|
tolarion wrote: BeginDoc / EndDoc
OK, so is it legal to have more than one pair of Begin/End Doc tags in the same job?
The problem with obtaining the filename is that the Win32 Spooler API doesn't provide it. All you get is a handle to the spool file, which you cannot touch until the job is complete. That's why you only get a Stream object from PrintSystemJobInfo.
|
|
|
|
|
You are right shouldn't be legal, but it works. I certainly will read the files on after the other ... if i get the Filename or a filled JobStream. I only need the Filename because the Stream object is always empty ... regardless of rights and printer type. Could be many files in a spool, so reading each and looking for the jobname would be digging to deep. Anny idea ?!
|
|
|
|
|
The only way to get the filename would be to get the handle that Win32 exposes to you, see the GetSpoolFileHandle[^] function, then enumerate the system handle table, looking for the handle returned, and get the filename. This is a very expensive operation to perform and by the time you get the filename the Spooler may have already closed the file and deleted it.
|
|
|
|
|
Thanks for your help, i will try GetSpoolFileHandle, but i am not sure how to get the system handle table and from there the filename ... and the file will still be there cause i stoped the Queue by using
Dim ps As New PrintServer(serverName, PrintSystemDesiredAccess.AdministrateServer)
Dim queue As New PrintQueue(ps, printerName, PrintSystemDesiredAccess.AdministratePrinter)
queue.Pause()
and after my operations i will start it again
queue.Resume()
Why could it not be all in system.printing ... now i must play around with pinvoke ...
|
|
|
|
|
Enumerating the system file handles requires admin permissions. Unless you're giving your app to a bunch of administrator user account (REALLY bad idea!), you're not going to be able to do this. This is NOT an operation typically done for printing. This is a technique usually used to diagnose system problems.
Quote:
tolarion wrote: and the file will still be there cause i stoped the Queue
Don't count on it.
tolarion wrote: Why could it not be all in system.printing ... now i must play around with pinvoke ...
The filename isn't supplied because Windows doesn't supply any method to get it. It has nothing to do with .NET. .NET is limited by the limitations in Windows.
modified 27-Jun-13 14:05pm.
|
|
|
|
|
Accessing the system spool needs admin permission, so i am already on that way ... not happy with it but we are on a Windows system not on Linux ... so everything needs admin ...
... and ... everything should be in a service, now i realized that printing from a service is *$&*# ... sorry ... but is there a other way ... in some forums they use PDF to print to and then combine the PDF and print it ... some SDKs are available, so there must be a way doing it ... i am not the one who gives up early ... but time is running away
|
|
|
|
|
I give up accessing the spool ... dave is right ... its a waste of time ...
Now i use pdfsharp.com[^]
Printing on a PDF Printer >> Combine the PDF >> Print the combined PDF on the HP9000 ... should be easy ?!
Hope this works out for me ... unfortunately i must use Acrobat Reader for printing ... but therefor it is free !
|
|
|
|
|
tolarion wrote: Printing on a PDF Printer >> Combine the PDF >> Print the combined
PDF on the HP9000 ... should be easy ?!
Doesn't that have the same problem as a docx file?
Open a command prompt and type COPY WordDoc1.docx + WordDoc2.docx WordDoc.docx, then try and open the WordDoc.docs file.
There's no "easy" way to achieve what you're trying. If it needs be done from several clients, then your best option would be to write your own device-driver. That would be done in an unmanaged language, not in .NET.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
|
Cool
|
|
|
|
|
I'm designing an application which consist of multiple clients that connect to a server using sockets. I'm trying to figure out a way to monitor the connection and if no data is transferred within a certain time from (say 1 minute) then the connection is closed (basically I'm trying to create a watchdog timer).
From what I've been reading it seems that I would need to use the AutoResetEvent class. The way I envisioned it working is that every time the server receives data from a client it resets the timer of the AutoResetEvent.WaitOne. What I've come up with so far is something like this in the server application:
Dim autoEvent as New AutoResetEvent(False)
If autoEvent.WaitOne(1000) Then
autoEvent.Reset
Else
Close connection and inform user
End If
When the socket receives data it will call autoEvent.Set which will cause the autoEvent.Reset method to be called. This would obviously be started on a new thread so it wouldn't block the main thread handling the data.
Is this correct or is there a better way to do this? Any links to creating a watchdog timer would be appreciated also. Thanks in advance for any help with this.
|
|
|
|
|
That seems like the best way to do it to me. BTW, your timeout is set to 1 second, not 1 minute. That could be for testing purposes. Just sayin'...
|
|
|
|
|
The timeout I just wrote that for the purposes of the post. When the autoEvent.Reset is called (as a result of autoEvent.Set being called), will the code in essence jump back to the autoEvent.WaitOne or will the code jump to after the If...Then...Else block?
|
|
|
|
|
|