Retrieving item text with JNA and SendMessage() - jna

I am attempting to retrieve the item text from a Win32 ListView-like control. I am using JNA and SendMessageW() to send LVM_GETITEMTEXTW to the control. I have been successful at retrieving the item count (via LVM_GETITEMCOUNT) but am stumped at this point. My User32 class is setup like so:
public interface MyUser32 extends User32 {
MyUser32 INSTANCE = (MyUser32)Native.loadLibrary("user32", MyUser32.class);
LRESULT SendMessageW(HWND hWnd, int msg, WPARAM wParam, LVITEM lParam);
}
My LVITEM class is setup like so:
public class LVITEM extends Structure{
public LVITEM() {
pszText = new Memory(MEMSIZE);
cchTextMax = MEMSIZE;
}
private static final int MEMSIZE = 256;
public UINT mask;
public int iItem;
public int iSubItem;
public UINT state;
public UINT stateMask;
public Pointer pszText;
public int cchTextMax;
public int iImage;
public LPARAM lParam;
public int iIndent;
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] { "mask", "iItem", "iSubItem", "state", "stateMask", "pszText", "cchTextMax", "iImage", "lParam", "iIndent"});
}
}
And the code that calls it all is like so:
MyUser32 u32 = MyUser32.INSTANCE;
LVITEM lvItem = new LVITEM();
WPARAM wPar = new WPARAM(1);
...
lvItem.iSubItem = 0;
res = u32.SendMessageW(handle, LVM_GETITEMTEXTW, wPar, lvItem);
System.out.println(res.intValue());
s = lvItem.pszText.getString(0);
System.out.println(s);
I've left out a bit of the code but I believe those are the important parts. My issue is that when I print out res.intValue() it is always 0 (meaning no text was returned) and when I print out the string value of pszText it is always some garbage characters. I'm completely stumped at this point so any suggestions are greatly appreciated. Thanks.

Related

Get data from a metatrader 4 alert

I use an indicator that generates alerts like: eur / USD Buy 1.122323, TP 1.131232, SL 1.114354, my question is how in an EA to read this data to execute the buy order.
cheat engine memory
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Telegram.Bot;
namespace ConsoleApp45
{
class Program
{
const int PROCESS_WM_READ = 0x0010;
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(int hProcess,
int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
public static void Main()
{
string ipek = "";
for (int i = 0; i < 10; i++)
{
Process process = Process.GetProcessesByName("terminal")[0];
IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);
int bytesRead = 0;
byte[] buffer = new byte[10];
//02DD12A4 cheat engine den alınan değer 0x02DD12A4 bu şekilde girilir.
ReadProcessMemory((int)processHandle, 0x02DD12A4, buffer, buffer.Length, ref bytesRead);
string yasin = Encoding.UTF8.GetString(buffer);
}
}
}
}

how to get JNA read back function's string result

public interface Kernel32 extends StdCallLibrary {
int GetComputerNameW(Memory lpBuffer, IntByReference lpnSize);
}
public class Kernel32Test {
private static final String THIS_PC_NAME = "tiangao-160";
private static Kernel32 kernel32;
#BeforeClass
public static void setUp() {
System.setProperty("jna.encoding", "GBK");
kernel32 = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
}
#AfterClass
public static void tearDown() {
System.setProperty("jna.encoding", null);
}
#Test
public void testGetComputerNameW() {
final Memory lpBuffer = new Memory(1024);
final IntByReference lpnSize = new IntByReference();
final int result = kernel32.GetComputerNameW(lpBuffer, lpnSize);
if (result != 0) {
throw new IllegalStateException(
"calling 'GetComputerNameW(lpBuffer, lpnSize)'failed,errorcode:" + result);
}
final int bufferSize = lpnSize.getValue();
System.out.println("value of 'lpnSize':" + bufferSize);
Assert.assertEquals(THIS_PC_NAME.getBytes().length + 1, bufferSize);
final String name = lpBuffer.getString(0);
System.out.println("value of 'lpBuffer':" + name);
Assert.assertEquals(THIS_PC_NAME, name);
}
}
The offical instructions says use byte[]、char[]、Memory or NIO Buffer for mapping char pointer in c native function.But I tried all of above, and String、WString、StringArrays、class extends PointType etc, all of them are no use.
Out parameter 'lpnSize' can return the corret buffer size,but 'lpBuffer' return 'x>'(i think it's random memory) or nothing no matter I mapping any java type.If i wrote someting to the 'lpBuffer' memory first, it would read the same things after calling native function.
How can I solve the problem?
You need to use Pointer.getString(0, true) to extract the unicode string returned by GetComputerNameW.
EDIT
You'll also need to call GetComputerNameW again with the length parameter initialized before the function will fill in the result. Either pass back the same IntByReference to a second call, or initialize the IntByReference to the size of your Memory buffer to have the buffer written to in the first call.

C# + Windows CE + Multiline & Align label

I need to make a multiline label with vertical and horizontal alignment and I don't know how I can do it !
I have found a way to make any control multiline with this function :
private const int BS_MULTILINE = 0x00002000;
private const int BS_CENTER = 0x00000300;
private const int BS_VCENTER = 0x00000C00;
private const int GWL_STYLE = -16;
[DllImport("coredll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("coredll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
public static void MakeControlMultiline(Control control) {
IntPtr hwnd = control.Handle;
int currentStyle = GetWindowLong(hwnd, GWL_STYLE);
int newStyle = SetWindowLong(hwnd, GWL_STYLE, currentStyle | /*BS_CENTER | BS_VCENTER | */BS_MULTILINE);
}
The "BS_CENTER | BS_VCENTER" is in comment since it doesn't work !
So I try to make a customControl where I realise both alignments, like this :
public partial class ImproveLabel : Control {
...
protected override void OnPaint(PaintEventArgs pe) {
Graphics g = pe.Graphics;
// text
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
drawFormat.LineAlignment = StringAlignment.Center;
g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), new Rectangle(0, 0, this.Width, this.Height), drawFormat);
// Calling the base class OnPaint
base.OnPaint(pe);
}
The strange thing here is that if I put both alignements to "Center", the multiline doesn't work anymore but if there is only the vertical alignment to "Center" and the horizontal alignment to "near", the multiline works.
I don't understand why it works this way but I need help to figure how I can get the 3 attributes working at the same time !
The code below is straight out of the P/Invoke SetWindowLong example.
private const int GWL_STYLE = -16;
private const int BS_CENTER = 0x00000300;
private const int BS_VCENTER = 0x00000C00;
private const int BS_MULTILINE = 0x00002000;
public static void SetButtonStyle(Button ctrl)
{
IntPtr hWnd;
int style;
// ctrl.Capture = true;
// hWnd = GetCapture();
// ctrl.Capture = false;
// Comment below and uncomment above if using Visual Studio 2003
hWnd = ctrl.Handle;
style = GetWindowLong(hWnd, GWL_STYLE);
SetWindowLong(hWnd, GWL_STYLE, (style | BS_CENTER | BS_VCENTER | BS_MULTILINE));
ctrl.Refresh();
}
It looks about exactly like yours, but I have not tested it personally.

progress bar for http request - Blackberry

in my project i am using popupscreen with GaugeField for http request.Currently we are just incrementing the value of gaugefield with fixed rate and after http response we just remove the popupscreen. so some times http request is completed when gauge field is in 40% or 60%.
But i want to synchronize gaugefield value with http request/responses. it means that popupscreen will always remove at 100%.
I don't have the code in front of me, but I something similar in a project several years ago.
I wrote a subclass of InputStream that wrapped around the InputStream object I got back from openInputStream(), reimplementing all the read() methods so they would increment a counter with the number of bytes read. Whenever the counter reached a certain threshold, it would update a GaugeField object that was passed into the subclass's constructor.
So your subclass would look something like this:
public GaugedInputStream extends InputStream
{
private InputStream _inputStream = null;
private GaugeField _gaugeField = null;
private int _counter = 0;
private int _threshold = 0;
public void GaugedInputStream(InputStream inputStream, GaugeField gaugeField)
{
_inputStream = inputStream;
_gaugeField = gaugeField;
... other constructor stuff ...
}
public int read()
{
int byte = _inputStream.read();
increment(1);
return byte;
}
public int read(byte[] b)
{
int bytes = _inputStream.read(b);
increment(bytes);
return bytes;
}
public int read(byte[] b, int off, int len)
{
int bytes = _inputStream.read(b, off, len);
increment(bytes);
return bytes;
}
... override other InputStream methods here ...
private void increment(int bytes)
{
_counter = _counter + bytes;
_threshold = _threshold + bytes;
updateGaugeIfNeeded();
}
private void updateGaugeIfNeeded()
{
if (_threshold > 100)
{
updateGauge();
_threshold = 0;
}
}
private void updateGauge()
{
... code to update the gauge ...
}
}
I'm leaving out a lot of the guts here, but I hope this sets you in the right direction.

How to Convert a C++ Structure into C# Structure

I need to convert a complex C++ structure into C# Structure,I have converted other structures in C#, this one contains some Two Dimensional array that is what the problem how to change it,Here is my structure,
this is other structure, which I Converted properly,
C++:
typedef struct
{
BYTE sSerialNumber[DH_SERIALNO_LEN]; BYTE byAlarmInPortNum;
BYTE byAlarmOutPortNum;
BYTE byDiskNum;
BYTE byDVRType;
BYTE byChanNum;
} NET_DEVICEINFO, *LPNET_DEVICEINFO;
C#:
public struct NET_DEVICEINFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] sSerialNumber;
public byte byAlarmInPortNum;
public byte byAlarmOutPortNum;
public byte byDiskNum;
public byte byDVRType;
public byte byChanNum;
}
And This structure Which I want Convert,this has 2 dim Array
C++:
typedef struct
{
DWORD dwSize;
DWORD dwDecProListNum;
char DecProName[DH_MAX_DECPRO_LIST_SIZE][DH_MAX_NAME_LEN];
DH_485_CFG stDecoder[DH_MAX_DECODER_NUM];
DWORD dw232FuncNameNum;
char s232FuncName[DH_MAX_232FUNCS][DH_MAX_NAME_LEN];
DH_RS232_CFG st232[DH_MAX_232_NUM];
} DHDEV_COMM_CFG;
and this is my try in C#,But it is giving me an error,
C#:
[StructLayout(LayoutKind.Sequential, Pack = 2, CharSet = CharSet.Auto)]
public struct DHDEV_COMM_CFG
{
public uint dwSize;
public uint dwDecProListNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public string[] DecProName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
DH_485_CFG[] stDecoder;
public uint dw232FuncNameNum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public string[] s232FuncName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public DH_RS232_CFG[] st232;
} ;
Please tell me how to to this....
By Bala
I know this is kinda useless 6 years down the road, but in any case, the converter from here worked nicely for me...

Resources