Страницы

Поиск по вопросам

воскресенье, 12 мая 2019 г.

C# Double.Parse вопрос

Есть строка "1.260", с помощью Double.Parse("1.260") получается число double 1.26.
Как сделать так, чтобы после парсинга 0 на конце остался, и мы получили переменную double a = 1.260?


Ответ

Значение 1.260 хранится в памяти как
00111111 11110100 00101000 11110101 11000010 10001111 01011100 00101001
0 на конце существует только в десятичном строковом представлении числа. Собственно, его вы и видите в отладчике. Его же вы видите при выводе, например, на консоль:
Console.WriteLine(1.26); // 1.26
если вам нужно получить ровно 3 символа после точки в строковом представлении - вы должны явно указать это при преобразовании числа обратно в строку:
string stringRepresentation = 1.26.ToString("0.000"); // 1.26 -> "1.260" Console.WriteLine(stringRepresentation);
или
Console.WriteLine("{0:0.000}", 1.26); // 1.260
подробно особенности форматирования чисел расписаны в MSDN, в статье Строки настраиваемых числовых форматов

Объединить два массива, только совпадающие элементы

long[] a = new long[]{45017,96741,11751,23772,58825}; long[] b = new long[]{23772,88781,23777};
Как 2 массива объединить в один, чтобы в новом (третьем) массиве были только совпадающие элементы, в данном случае 23772 ?


Ответ

Как вариант:
private static List asList(long[] array) { List res = new ArrayList<>(array.length); for (long l : array) { res.add(l); } return res; }
public static void main(String[] args) { long[] a = new long[]{45017,96741,11751,23772,58825}; long[] b = new long[]{23772,88781,23777}; List cList = asList(a); cList.retainAll(asList(b));
System.out.println(cList); }

Как нарисовать круг в XML

Как нарисовать незакрашенный круг (желательно с возможностью задавать ширину контура), который будет использоваться в android?
Картинка png страдает качеством, поэтому лучше использовать xml.
И еще он должен быть полностью прозрачным, кроме самой линии контура.


Ответ

По идее как раз таки и надо использовать png. Просто надо грамотно картину разложить по папкам в drawable. Круг в xml нарисовать можно таким образом:

Как получить коллекцию окон под курсором мыши?

Есть WinAPI функция WindowFromPoint. Она возвращает хэндл окна под курсором. А как мне получить все окна под курсором?
На самом деле мне нужно получить второе окно под курсором, но скорее всего решение этой задачи сведется к возврату всех окон и выбору из них второго.
Полагаю, что dotNet не знает, как это сделать, но на всякий случай добавил тег языка, в котором мне это потребовалось, на случай если таки можно обойтись без WinAPI.
UPD:
Написал такую функцию, но она не всегда возвращает правильный результат (часто возвращает не то окно). Посмотрите, что может быть не так. Координаты курсора определяются верно (проверил).
public static Window SecondFromCursor() { var curPos = new System.Drawing.Point(); if (EtherDragDrop.GetCursorPos(ref curPos)) { var wRect = new Int32Rect(); var k = 0; for (IntPtr hWnd = GetTopWindow(IntPtr.Zero); hWnd != IntPtr.Zero; hWnd = GetWindow(hWnd, GW_HWNDNEXT)) { if (GetWindowRect(hWnd, ref wRect)) { if ((curPos.X>wRect.X && curPos.X<(wRect.X+wRect.Width)) && (curPos.Y > wRect.Y && curPos.Y < (wRect.Y + wRect.Height))) { k++; if (k == 2) { //Console.WriteLine($"{hWnd}: ({wRect.X}; {wRect.Y}) ({wRect.Width}; {wRect.Height}). TopHwnd ({GetTopWindow(IntPtr.Zero)})"); var hs = HwndSource.FromHwnd(hWnd); return hs?.RootVisual as Window; } } } }
} return null; }
UPD2:
Вот тестовое использование функции
var wnd = EtherApp.SecondFromCursor(); if (wnd != null) { var cp = new System.Drawing.Point(); GetCursorPos(ref cp); wnd.Title = $"({cp.X}; {cp.Y})"; }
Происходит при перемещении окна (LocationChanged). Так вот, я перемещаю одно окно над другим (этого же приложения). В результате ожидаю, на нижнем окне изменение заголовка на координаты курсора. Окно занимает большую часть экрана. Двигаю в одной его области и меняется его заголовок. Двигаю в другой области, меняется заголовок того окна, которое двигаю (то есть верхнего). Двигаю еще по каким то местам и ничего не меняется. В консоль выводятся при этом неизвестные мне хэндлы (если раскомментировать вывод в рабочей функции). Я не могу найти закономерность.
UPD3:
Еще раз перечитал описание функции GetWindowRect. Она возвращает две координаты точек, а я их использовал как координату левой верхней и размеры. Исправил, но проблему это не решило. Координаты окон вычисляются теперь верно, но почему функция иногда возвращает какие то другие окна или самое верхнее окно (то окно, которое я двигаю), я не понимаю. У нее в логике прописано, что она должна возвращает результат только когда k==2
UPD4:
Когда мне возвращается верхнее окно (которое я перемещаю), его hWnd при этом отличается от того, что получено при помощи GetTopWindow. Получается, что на одно и то же визуальное окно ссылаются разные hWnd? Как так?


Ответ

В консоль выводятся при этом неизвестные мне хэндлы
Многие из этих окон невидимы или размер у них 1х1.
Для того, чтобы получить список всех окон под курсором, надо у WinAPI функции WindowFromPoint получить hwnd, а затем вызывать GetWindow. При этом надо для каждого окна получить его границы, т.е. Rectangle и выбрать только те, окна у которых границы пересекаются с границами окна под курсором мыши.
Ниже пример приложения TEST, в котором выводится список окон под курсором мыши.

// Microsoft (R) Roslyn C# Compiler version 1.1.0.51204 #r "System.Windows.Forms"
using System.Windows.Forms; using System.Runtime.InteropServices; using System.Drawing;
enum Gw : uint { GW_HWNDNEXT = 2, GW_HWNDPREV = 3 } [DllImport("user32.dll", SetLastError = true)] static extern IntPtr GetWindow(IntPtr hWnd, Gw uCmd); [DllImport("user32.dll")] static extern IntPtr WindowFromPoint(System.Drawing.Point p); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetWindowTextLength(IntPtr hWnd); static string GetTitle(IntPtr hwnd) { var sb = new StringBuilder(GetWindowTextLength(hwnd) * 2); GetWindowText(hwnd, sb, sb.Capacity); return sb.ToString(); } [StructLayout(LayoutKind.Sequential)] struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll", SetLastError = true)] static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); static Rectangle GetRectangle(IntPtr hwnd) { var r = new RECT(); GetWindowRect(hwnd, out r); return Rectangle.FromLTRB(r.Left, r.Top, r.Right, r.Bottom); } [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool IsWindowVisible(IntPtr hWnd);

static IEnumerable GetWindows(IntPtr hwnd, Gw gw) { for (var h = hwnd; h != IntPtr.Zero; h = GetWindow(h, gw)) yield return h; }
class Info { public Info(IntPtr hwnd) { this.Hwnd = hwnd; } public Rectangle Bounds { get { return GetRectangle(this.Hwnd); } } public IntPtr Hwnd; public string Title { get { return GetTitle(this.Hwnd); } } public bool Visible { get { return IsWindowVisible(this.Hwnd); } } public override string ToString() { return String.Format("{0,15}\t{1,-50}\t{2}", this.Hwnd, this.Bounds, this.Title); } }

var frm = new Form() { Width = 800, Height = 500, TopMost = true, Text = "TEST" }; var rtb = new RichTextBox() { Parent = frm, Dock = DockStyle.Fill, WordWrap = false }; new System.Windows.Forms.Timer() { Interval = 500, Enabled = true } .Tick += (s, e) => { var pos = Cursor.Position; var i = new Info(WindowFromPoint(pos)); var p = GetWindows(i.Hwnd, Gw.GW_HWNDNEXT) .Select(h => new Info(h)) .Where(v => v.Visible && Control.FromHandle(v.Hwnd) != rtb) .Where(v => !v.Bounds.IsEmpty && v.Bounds.IntersectsWith(i.Bounds)); rtb.Text = String.Join("
", p); }; frm.ShowDialog();

Для компиляции кода и запуска приложения, например, в Visual Studio Community 2015 надо открыть View - Other Windows - C# Interactive, скопировать в него код и нажать Enter.
Visual Studio Community 2015 - бесплатная версия, ее можно скачать тут

Как узнать, откуда был инициирован callback?

Есть функция, использующая внутри вызов с асинхронным callback ($.ajax или просто window.setTimeout):
function someFuncton() { window.setTimeout(function() { debugger; }); } function a() { someFuncton(); } function b() { someFuncton(); } b();
В отладчике хрома при этом callstack выглядит как
(anonymous function) (js:15)
Как, при остановке отладчиком на строчке debugger;, узнать, откуда был инициирован callback - из a() или из b()?


Ответ

В стеке вызовов, предварительно установив галочку "Async" - асинхронные вызовы захватываются только когда установлена:

Печать jpg файла в С#

Как из программы написанной на С# напечатать файл с расширением .jpg ?


Ответ

// Путь к изображению. string file = @"C:\1.png";
using(var pd = new System.Drawing.Printing.PrintDocument()) { pd.PrintPage += (o,e) => { var img = System.Drawing.Image.FromFile(file);
e.Graphics.DrawImage(img, new Point(50, 50)); }; pd.Print(); }

Автоматическое растягивание элементов WPF под размер родителя (растягивание внутри ListBox)

Есть ListBox выводящий список заказов