Страницы

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

пятница, 11 января 2019 г.

Ошибка 6 (неверный дескриптор) - в чём причина?

Для начала мне требуется найти некоторый файл:
HANDLE hExample4; HANDLE hExample24; WIN32_FIND_DATA fd; hExample4 = FindFirstFile("Example4.bin",&fd); hExample24 = FindFirstFile("Example24.bin",&fd);
Так вот, после того, как я начинаю работать с этими дескрипторами, вызов любой функции типа SetEndOfFile(), GetFileSize() и т. д. выдаёт ошибку, а при вызове GetLastError() можно увидеть, что это ошибка 6 (неверный дескриптор).
Что тут не так?


Ответ

FindFirstFile возвращает дескриптор поиска(не тот дескриптор, который создается при открытии файла с помощью функции CreateFile, назовем его файловый дескриптор). Поэтому вы его не можете использовать в функциях для работы с файлами типа SetEndOfFile, GetFileSize. Дескриптор поиска вы можете использовать только для дальнейшего поиска других файлов с помощью функции FindNextFile
Когда дескриптор поиска больше не нужен, вы его должны закрыть с помощью функции FindClose, именно с помощью этой функции, а не с помощью функции CloseHandle, который мы закрываем файловый дескриптор, когда создаем его с помощью функции CreateFile
Поэтому если вы нашли этот файл, то для получения файлового дескриптора вызовите функцию CreateFile с флагом OPEN_EXISTING, если вам он действительно нужен.
P.S Функция FindFirstFile возвращает структуру LPWIN32_FIND_DATA, из которой вы можете получить размер файла во так
LARGE_INTEGER filesize; filesize.LowPart = fd.nFileSizeLow; filesize.HighPart = fd.nFileSizeHigh; _tprintf(TEXT(" %s %ld bytes
"), fd.cFileName, filesize.QuadPart);
FindFirstFile Function Listing the Files in Directory Example

PHP PDO в чем разница ATTR_EMULATE_PREPARES, false и true

Пробовал вставлять значения разных типов данных в колонки с разными типами данных при ATTR_EMULATE_PREPARES, false и true, разницы не увидел, может кто объяснить в чем отличие?
//типы колонов r1 = int, r2 = varchar, r3 = bool
$pdo = new PDO('mysql:host=localhost;dbname=test;charser=utf8', 'root', ''); $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$smt = $pdo->prepare('INSERT INTO pwnd (r1, r2 ,r3) VALUES (:r1, :r2, :r3)'); echo $smt->execute([':r1' => 'a2', ':r3' => 'false', ':r2' => true]);


Ответ

С PDO::ATTR_EMULATE_PREPARES в значении true за обработку подготовленных выражений отвечает сам PDO. В базу данных передаётся чистый запрос с уже подставленными и корректно экранированными данными (только в dsn не забывайте правильно charset указывать).
PDO::ATTR_EMULATE_PREPARES в значении false именно использует штатный механизм СУБД для подготовки запроса и затем отдельным обращением передаёт данные для этого запроса. Т.е. нормальные, реальные подготовленные выражения.
Из не очевидных моментов:
для сложных запросов дико удобно использовать именованные параметры несколько раз. Какой-нибудь where user_from = :id or user_to = :id и передать только один id. Такое возможно только с эмуляцией запросов. специфика конкретных СУБД. Какие-то СУБД из тех, что умеет PDO могут не уметь подготовленные выражения. Например, очень популярный PgBouncer (пул коннектов для PostgreSQL) не умеет обрабатывать подготовленные выражения. С эмуляцией выражений можно в коде проекта пользоваться удобствами API с prepare вопрос с тем, что подготовленный запрос разбирается и строит план один раз и затем только выполняется - на самом деле гораздо сложнее. Тот же mysql сохраняет запрос только в рамках соединения. Поэтому в типичном сценарии использования "подготовил, выполнил, закрыл соединение" никаких плюсов реальное препарирование не даёт. А кэширование плана между соединениями - по-моему (сам с этой СУБД не работал), есть в Oracle и приносит некоторое количество головной боли, ведь оптимальный план запроса в немалой степени зависит от самих данных.

Диалог с предложением включить GPS

Когда заходишь в Google Maps и у тебя выключен GPS, Андроид тебе предложит включить его диалогом с двумя кнопками. При нажатии на ОК - GPS включится.
Как сделать такой же диалог в своем приложении ?
И да, я правильно понимаю, что программно я никак не могу включить GPS без спрашивания пользователя ?


Ответ

Опросите систему включен ли GPS.
public boolean isGeoDisabled() { LocationManager mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); boolean mIsGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); boolean mIsNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); boolean mIsGeoDisabled = !mIsGPSEnabled && !mIsNetworkEnabled; return mIsGeoDisabled; }
если нет, покажите диалог с предложением включить, при согласии отправьте пользователя в настройки
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));

Цвет строки заголовка

Как в uwp программно изменить цвет строки заголовка?

Спасибо.


Ответ

using Windows.UI; using Windows.UI.ViewManagement;
...
var view = ApplicationView.GetForCurrentView(); view.TitleBar.BackgroundColor = Colors.DarkGreen;
Другие возможности по кастомизации цвета тут

Существует пример реализации ViewPager внутри DialogFragmen?

Есть примеры кода реализации ViewPager внутри какого либо DialogFragment? Находил некоторые примеры, но каждый раз возникали разные ошибки которые не позволяли понять в чем все таки проблема, по сему прошу полный пример от и до содержащий по возможности xml


Ответ


Tab_1.class
public class Tab_1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.tab_1, container, false); } }
Tab_2.class
public class Tab_2 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.tab_2, container, false); } }
Tab_3.class
public class Tab_3 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.tab_3, container, false); } }
tab_1.xml


tab_2.xml


tab_3.xml


MainActivity.class
Кнопка вызова кастомного диалога.
public class MainActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }
public void onClick(View v){ new FragmentsPopup().show(getSupportFragmentManager(), ""); } }
activity_main.xml

Конструкция *++argv[0] в языке Си

Как в этом примере использования указателей работает конструкция *++argv[0] во внутреннем цикле?
#include #include
int main(int argc, char *argv[]) { int c, except = 0, number = 0;
while(--argc > 0 && (*++argv)[0] == '-') { printf("argv = %s
", *argv); while(c = *++argv[0]) switch(c){ case 'x': except = 1; break; case 'n': number = 1; break; default: printf("Illegal option: %c
", c); argc = 0; break; }
}
printf("[DEBUG]: argc = %d
", argc);
if(argc != 1) printf("Usage: -x -n
"); else printf("x = %d, n = %d
", except, number); return 0; }
Разберу похожую конструкцию (*++argv)[0] во внешнем цикле. Здесь берется нулевой символ строки, которая содержит один из аргументов. Скобки [] имеют более высокий приоритет, чем инкремент и ссылка, поэтому *++argv заключается в скобки. Нулевой элемент массива argv это указатель на имя программы, поэтому инкрементом переходим к следующий строке. После этого разыменовываем указатель и получаем строку. Применение скобок [0] дает нулевой символ этой строки.
Конструкция *++argv[0] мне совсем непонятна. Здесь должен быть проход по строке-аргументу. Это нужно для того, чтобы поддерживались не только ключи типа -x -n, но и ключи вида -nx. Для чего здесь [0]? Как работает выражение целиком?


Ответ

Ну а здесь просто проход посимвольно - как вы написали сами, квадратные скобки имеют более высокий приоритет, так что просто увеличивается указатель argv[0], который изначально указывает на начало строки аргументов, а разыменование дает очередной символ...
Т.е. если вызывается программа так, что argv[1] == -abcxn, то после первой строки (++argv)[0] указатель argv[0] указывает на строку -abcxn. Первое разыменование (в первом while) дает '-', затем, во втором while, просто перебираются все символы строки - a, b, c, x, n

Как сделать, чтобы EditText не увеличивался по сторонам?

Как сделать, чтобы EditText не увеличивался в стороны, когда в него вводят текст?

Код разметки (EditText'ы в первых двух LinearLayout'ах):