Страницы

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

воскресенье, 22 декабря 2019 г.

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

#c_sharp #winforms #winapi #interop


Как получить информацию о любом из окон Windows, которое находится под курсором мыши?
Надо реализовать часть возможностей, которые есть в утилите Microsoft Spyxx.exe и
выводить следующую иформацию: 


HWND, 
Class Name, 
Window Styles, 
RGB цвет пикселя, 
размеры окна.  


Как получить координату мыши за пределами WinForms Application?
Как получить необходимую информацию об окнах и вывести, например, в таком виде:


    


Ответы

Ответ 1



Для создания такого приложения надо использовать Win API функции для работы с окнами Windows. Позиция курсора определяется по таймеру. // 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; using System.Reflection; // Win API functions [DllImport("user32.dll")] static extern IntPtr WindowFromPoint(Point p); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int GetClassName(HandleRef hWnd, StringBuilder cName, int maxCount); [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern int GetWindowLong(HandleRef hWnd, int nIndex); [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(HandleRef hwnd, out RECT lpRect); [DllImport("user32.dll")] static extern bool GetClientRect(HandleRef hWnd, out RECT lpRect); [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr hwnd); [DllImport("user32.dll")] static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc); [DllImport("gdi32.dll")] static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos); static public Color GetPixelColor(Point point) { var hdc = GetDC(IntPtr.Zero); var p = GetPixel(hdc, point.X, point.Y); ReleaseDC(IntPtr.Zero, hdc); return Color.FromArgb((int)(p & 0x000000FF), (int)(p & 0x0000FF00) >> 8, (int)(p & 0x00FF0000) >> 16); } [DllImport("user32")] static extern int GetWindowThreadProcessId(HandleRef hWnd, out int processId); class WindowStyles { static KeyValuePair[] enums; static WindowStyles() { // читаем значения полей WS_* из internal class NativeMethods. var t = typeof(Form).Assembly.GetType("System.Windows.Forms.NativeMethods"); var b = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public; enums = t.GetFields(b) .Where(fi => fi.Name.StartsWith("WS_")) .Select(fi => new KeyValuePair((int)fi.GetValue(null), fi.Name)) .ToArray(); } static public string[] ReadStyles(HandleRef hr) { var v = GetWindowLong(hr, -16); // GWL_STYLE var res = new List(); for (int i = 0; i < enums.Length; i++) { var wsi = enums[i]; if ((v & wsi.Key) == wsi.Key) res.Add(wsi.Value); } return res.ToArray(); } } class HWndSpy { Timer Timer; public HWndSpy() { this.Timer = new Timer() { Interval = 500, Enabled = true }; this.Timer.Tick += (s, e) => { this.Point = Cursor.Position; // WinAPI: GetCursorPos this.HWnd = WindowFromPoint(this.Point); var hr = new HandleRef(this, this.HWnd); var cn = new StringBuilder(256); GetClassName(hr, cn, cn.Capacity); this.ClassName = cn.ToString(); this.Styles = WindowStyles.ReadStyles(hr); var r = new RECT(); GetWindowRect(hr, out r); this.WindowRect = Rectangle.FromLTRB(r.Left, r.Top, r.Right, r.Bottom); GetClientRect(hr, out r); this.ClientRect = Rectangle.FromLTRB(r.Left, r.Top, r.Right, r.Bottom); this.Color = GetPixelColor(this.Point); int pid; GetWindowThreadProcessId(hr, out pid); this.ProcessId = pid; this.Changed(this, EventArgs.Empty); }; } public IntPtr HWnd { get; private set; } public String ClassName { get; private set; } public String[] Styles { get; private set; } public Rectangle WindowRect { get; private set; } public Rectangle ClientRect { get; private set; } public Point Point { get; private set; } public Color Color { get; private set; } public int ProcessId { get; private set; } public event EventHandler Changed = delegate { }; } var frm = new Form() { Width = 570, Height = 170, TopMost = true }; Func label = (d) => new Label() { Parent = frm, Dock = d, TextAlign = ContentAlignment.TopLeft }; var style = label(DockStyle.Fill); var cname = label(DockStyle.Top); var bounds = label(DockStyle.Top); var hwnd = label(DockStyle.Top); var ws = new HWndSpy(); ws.Changed += (s, e) => { hwnd.Text = "HWnd: " + ws.HWnd + " (ProcessID:" + ws.ProcessId + ")"; bounds.Text = "WindowRect: " + ws.WindowRect + "; ClientRect: " + ws.ClientRect; cname.Text = "ClassName: " + ws.ClassName; style.Text = "Styles: " + String.Join("; ", ws.Styles); frm.Text = String.Concat( "HWndSpy -- Point: ", ws.Point, "; Color: ", ColorTranslator.ToHtml(ws.Color)); }; frm.ShowDialog(); Для компиляции кода и запуска приложения, например, в Visual Studio Community 2015 надо открыть View - Other Windows - C# Interactive, скопировать в него код и нажать Enter. Visual Studio Community 2015 - бесплатная версия, ее можно скачать тут.

Как сделать свою библиотеку подключаемой через зависимости gradle

#java #android #github #gradle


На github часто можно встретить такой код для build.gradle файла -

dependencies {
    compile 'com.lusfold.spinnerloading:spinnerloading:1.0.0'
}


Если добавить эту зависимость в проект, то подключаемая библиотека компилируется
автоматически, что очень упрощает процесс её подключения.

Такой вопрос - если я сам создал какую-нибудь библиотеку и выложил её на github,
как мне сгенерировать такую же ссылку, чтобы люди (и я, при необходимости повторного
использования) могли так же просто подключать мою библиотеку в свои проекты? 
    


Ответы

Ответ 1



Во первых подключаемая библиотека не компилируется, она скачивается с maven репозитория уже скомпилированная. Ну а что бы пользователи смогли пользоваться вашей библиотекой подключая её похожим образом нужно выложить её в публично доступный репозиторий. Как это сделать хорошо описано в этой статье. Там правда немного избыточно, для публикации библиотеки в jCenter шаги 2 и 3 не нужны, они нужны для публикации ещё и в Maven Central. Есть ещё совсем простой способ именно для GitHub: jitpack.io. Но с ним пользователю придётся добавить, кроме непосредственно строки описывающей зависимость от Вашей библиотеки, ещё и ссылку на репозиторий. В общем у них на сайте всё подробно расписано.

Как добиться подобного?

#html #css #вёрстка




Суть проблемы: таблицами (или div-ами) добиться разделения колонок так, как на скрине.
У границ tr, td могут ли быть отступы от краёв именно по границам? Или можно сверстать
это 3-мя div-ами?
    


Ответы

Ответ 1



Таблицу вкладываем в любой блочный элемент с рамкой. Для каждой ячейки, начиная с второй устанавливаем только левую часть границы border-left. Не забываем про border-collapse, иначе разделитель не будет сплошной. div{ border: 1px solid black; border-radius: 15px; padding: 8px; display: inline-block; } table{ border-collapse: collapse; } th,td{ padding: 5px; text-align: center; border-left: 1px solid black; } th:first-child,td:first-child{ border-left: 0px; //убираем черту слева } demo

Как лучше разбивать классы Android-проекта? [закрыт]

#java #android #android_sdk


        
             
                
                    
                        
                            Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Update the question so it
can be answered with facts and citations by editing this post.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Как лучше всего разбивать классы по пакетам:
-по назначению

-database
-network
-reader
-ui


-по классам

-activities
-adapters
-fragments
-model
-utils
-widgets


Best-practices с Github рекомендуют разбивать так, как показано во втором примере,
но из-за этого код приложения не будет модульным и такой код будет трудно переиспользовать
(поправьте, если это не так). Как быть?

Можете также показать свои варианты.
    


Ответы

Ответ 1



Мне кажется ваши два варианта вполне сочетаются друг с другом: -database -model -network -model -request -ui -activities -adapters -fragments -widgets -utils Я обычно как то так организую. Но вообще тема довольно холливарная.

Поиск последовательности в таблице

#sql_server


В БД есть таблица в два столбца с большим количеством записей. Первый столбец - id,
второй - числа с плавающей точкой.

Дана последовательность трёх чисел с плавающей точкой. Нужно узнать, встречается
ли такая последовательность в БД - допустим с 10 id по 12. Если есть - то нужен id
начального числа.

Как это лучше всего сделать с наименьшими энергозатратами? Выбрать в массив вхождения
по первому числу и в затем цикле проверить остальные 2? Но записей в ней очень много
- такая переборка займёт большое время.

Дополню, чтобы понятней задача была. Вот БД:


4.3422
5.3434
3.3243
4.2453
2.3445
и т.д.


Дана последовательность 3х чисел: 5.3434, 3.3243, 4.2453. Нужно найти эту последовательность
в базе данных - есть ли она вообще, а если есть, то вернуть что они находятся в том
же порядке со 2 id по 4. 
    


Ответы

Ответ 1



Стандартная задача на поиск подпоследовательности в последовательности. Далее два запроса, которые ищут все вхождения подпоследовательности в последовательность: 1) вариант для подпосл. из 3х элементов. работает только если в Id нет пропусков значений. 2) для любых подпоследовательностей. DECLARE @T1 TABLE(Id INT, Value MONEY) DECLARE @T2 TABLE(Id INT, Value MONEY) INSERT @T1 VALUES (1,1),(2,2),(3,3),(4,4),(5,3), (6,2),(7,3),(8,4),(9,3),(10,2) INSERT @T2 VALUES (1,2),(2,3),(3,4) --вариант для трёх, работает только если в Id нет пропусков значений. SELECT MIN(T1.Id) Id FROM @T1 T1 JOIN @T2 T2 ON T1.Value = T2.Value GROUP BY T1.Id - T2.Id HAVING COUNT(*) = 3 --более общий вариант, работает с любыми последовательностями SELECT MIN(T1.Id) Id FROM (SELECT ROW_NUMBER()OVER(ORDER BY Id)N,* FROM @T1)T1 JOIN (SELECT ROW_NUMBER()OVER(ORDER BY Id)N,COUNT(*)OVER()C,* FROM @T2)T2 ON T1.Value = T2.Value GROUP BY T1.N - T2.N HAVING COUNT(*)=MAX(C) UPD: если вы заранее знаете все три значения, то пожалуй лучше встроить конструктор таблицы прямо в запрос. Ещё 2 варианта: DECLARE @T1 TABLE(Id INT, Value MONEY) INSERT @T1 VALUES (1,1),(2,2),(3,3),(4,4),(5,3), (6,2),(7,3),(8,4),(9,3),(10,2) DECLARE @Param1 MONEY = 2, @Param2 MONEY = 3, @Param3 MONEY = 4 --В столбце Id таблички @T1 нет пропусков: SELECT MIN(T1.Id) Id FROM @T1 T1 JOIN (VALUES(1,@Param1),(2,@Param2),(3,@Param3))T2(Id, Value) ON T1.Value = T2.Value GROUP BY T1.Id - T2.Id HAVING COUNT(*)=3 --В столбце Id таблички @T1 есть пропуски: SELECT MIN(T1.Id) Id FROM (SELECT ROW_NUMBER()OVER(ORDER BY Id)N,* FROM @T1)T1 JOIN (VALUES(1,@Param1),(2,@Param2),(3,@Param3))T2(N, Value) ON T1.Value = T2.Value GROUP BY T1.N - T2.N HAVING COUNT(*)=3

Возможность програмирования на планшете [закрыт]

#android


        
             
                
                    
                        
                            Закрыт. На этот вопрос невозможно дать объективный ответ.
Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Update the question so it
can be answered with facts and citations by editing this post.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Здравствуйте. Ничего не понимаю в программировании, но хочу начать обучатся. Подскажите,
возможно ли программирование на планшете?
К компьютеру пока не имею доступа.  
    


Ответы

Ответ 1



Для разработки Android-программ на языке программирования Java есть IDE для android-устройств - AIDE. Возможности ее довольно скромны, по сравнению с десктопными средствами разработки и для начального обучения это тоже не самый лучший вариант, но под платформу Android - лучшее из того, что есть. Ссылка на Google Play C другими языками программирования на платформе Android все несколько печально. Есть инструменты для работы с С\С++, но начинать учиться программированию на этих языках крайне не рекомендуется. Так же есть некие инструменты - DeuterIDE, список поддерживаемых языков впечатляет (40 штук) и Run The Code (20 языков), но что это такое и насколько пригодно для использования сказать не могу, не пользовался.

Ответ 2



Если речь именно об обучении программированию, а не о серьёзной разработке на планшете, можно посмотреть на TouchDevelop от Microsoft. Он реализован прямо в браузере, интерфейс изначально проектировался для мобильных платформ. Внутри использует JavaScript, но вам об этом знать пока необязательно (ой, уже поздно). Возможности у него, конечно, скромные. И полученные знания очень слабо привязываются к конкретному языку, поэтому этого вам хватит до ухода с уровня "абсолютный начинающий". Далее вы, вероятно, захотите работать с реальными языками, и тут уже будут проблемы, поскольку они приспособлены для работы с полноценной клавиатурой, на которой удобно набирать произвольный текст, богатый на пунктуацию. На планшетах пунктуация обычно запрятана в отдельный раздел клавиатуры. Каждый раз на него переключаться это боль. В какой-то мере помогает "хакерская клавиатура" (Hacker's keyboard, см. Google Play), делая клавиатуру чуть более похожей на обычную (более полная раскладка)... Так уж сконструированы используемые нынче (нормальные, не эзотерические) языки. Всем нужна пунктуация. Даже Ruby, в котором из известных мне языков её меньше всего, без пунктуации далеко не уехать. Возможным спасением мог бы стать редактор, умеющий расставлять пунктуацию (большую её часть хотя бы) самостоятельно, примерно как это делает Parinfer на основе отступов строк (количества пробелов в начале каждой строки), но это уже далеко не для начинающих, да и ни одна реализация, адаптированная под тачскрины мне пока неизвестна. Впрочем, в связи с успешным переносом ClojureScript в браузер, могут возникнуть! Короче, проблема не в том, что это неудобно. А в том, что инструментов никто не делает, чтобы это стало удобным. Для современных сред разработки считается уже почти требованием выполнение крупных преобразований над кодом. Если реализовать и более мелкие и хорошенько разложить по интерфейсу... теоретически, это может быть удобно. Но этим мало кто занимается.

Ответ 3



Купите планшет на Windows установите IntelliJ IDEA + JDK и будет вам счастье. У меня так супруга долгое время изучала Java.

Выезжающий View

#android #android_layout #android_animation




Есть приложение с нижним тулбаром. Нужно сделать окно камеры, которое выезжает снизу
по нажатию на левую кнопку. Окно должно выезжать на 1/3 экрана, тулбар должен быть
над ним. Сделал камеру в SurfaceView. Как сделать выезжание?




    

    

        

        

        

        

    

    





    


Ответы

Ответ 1



Camera_Activity.class public class Camera_Activity extends AppCompatActivity { ImageButton btn_camera; ImageButton btn_mic; SurfaceView sv; LinearLayout show_video; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.anim_footer); show_video = (LinearLayout) findViewById(R.id.show_video); btn_camera = (ImageButton) findViewById(R.id.btn_camera); btn_mic = (ImageButton) findViewById(R.id.btn_mic); sv = (SurfaceView) findViewById(R.id.camera_view); btn_camera.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (sv.getVisibility() == View.GONE) { sv.setVisibility(View.VISIBLE); final Animation show = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.show_video); show_video.startAnimation(show); } } }); btn_mic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (sv.getVisibility() == View.VISIBLE) { final Animation hide = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.hide_video); hide.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { sv.setVisibility(View.GONE); } @Override public void onAnimationRepeat(Animation animation) { } }); show_video.startAnimation(hide); } } }); } } anim_footer.xml Две анимации: show_video.xml hide_video.xml Результат: Я старался по мин. задеть Вашу разметку, получается что добавился только LinerLayout, как контейнер для всего этого дела внизу. Иконки стандартные. В целом в коде особого нет ничего, но один момент я думаю стоит объяснить. Анимация translate: так как панелька у нас всегда видна, поэтому требуется выдвигать панель меньше на этот размер, но его подсчитать не будет сложности, даже если динамически будет меняться, просто придется анимацию переписывать программно. Да и в одной из анимации 1% больше, это фича, чтоб старт казался плавней, можете поставить на 85% поймете почему. Остальное вроде все по стандарту.