Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Клуб профессиональных программистов :: Выпуск #81


Клуб профессиональных программистов "Весельчак У"
Информационная рассылка сайта и форума.  Выпуск No81 (2009-11-22).

Здравствуйте, уважаемые читатели!

Содержание.



Предисловие.


Иногда в практике программиста возникает ситуация, когда стандартный набор элементов управления (в статье будет использоваться сокращение ЭУ) старой доброй Visual Studio 6...10 не содержит того ЭУ, который сейчас позарез понадобился. Где-то в Интернете, возможно, лежит этот элемент, но его почему-то никак не удаётся найти, а всё, что нашлось, не то, не то, не то...  Например, нам срочно понадобилось сделать ЭУ, который <придумаем позже, что он делает, наберитесь терпения>.

В этой статье я подробно опишу, как создать свой графический ЭУ. Все действия, описанные в статье, производятся в среде MS Visual Studio 2008 (Visual Studio 9.0), но версия студии — это не так уж важно (код класса будет протестирован и в VS6), важнее то, что работа выполняется при помощи библиотеки MFC, интерфейс которой практически не меняется. Да, кстати, у меня "русифицированная" версия студии, поэтому все названия пунктов меню оттуда — на русском. Непривычно, конечно, но как они в английской версии называются, я все точно не помню, поэтому буду писать на русском. Кроме того, некоторые слова явно коряво переведены, но для достоверности буду писать так, как они есть в студии.

В статье собираюсь разобрать следующие вопросы:


  • создание класс ЭУ, от чего можно наследовать,
  • размещение на форме (диалоге, view) при помощи визарда или "вручную",
  • "прозрачность" (не путать с полупрозрачностью),
  • отрисовка контента с учётом текущего размера ЭУ,
  • рассчёт координат элементов графики и интерактивность,
  • работа с мышью,
  • определение выхода курсора мыши за край ЭУ и захода обратно,
  • захват мыши,
  • борьба с мерцанием при отрисовке,
  • обрезание графики в размер определённого прямоугольника,
  • дочерние окна элемента управления, их размещение и обработка сообщений от них.

Целиком прочесть статью можно на нашем сайте, в разделе «Программирование в ОС::Windows».


  • Программирование :: Общий
  •   Всем доброго дня/вечера.

    Есть dll-ка, она собирается из нескольких .cpp файлов, в каждом из которых есть экспортируемые функции.

    Вопрос: есть ли единый стандарт, который оговаривает в каком порядке все экспортируемые функции появяться в .def-файле?

    Например, в порядке обявления в хедере?


    Проблема в том, что есть чужой код, который ищет и вызывает (из dll-ки) функцию по номеру (а не по имени). Поэтому становиться выжным порядок функций в .def-файле.

    "Руками" правильный .def я могу написать, но автоматически он генериться не правильно :(


    Есть подозрение, что каждый копилятор делает .def как хочет.... Так ли это?
  • Программирование :: Технологии разработки программных систем
  • Вопрос про само-обновляемое ПО и как его правильно вписать в архитектуру WinPX и более мудренных в плане защиты Vista и W7.

    Имеется ПО, написанное за 10 или более лет несколькими программистами. Периодически в нем исправляются баги и добавляются фичи. Соответственно, после этого надо обновить установку на всех машинах, где это ПО используется. Машины не персонализированы — все пользователи логинятся в домене Win2003.

    ПО состоит их набора exe, пары dll, сопутствующих неисполняемых файлов и библиотеки в распотрошенном виде.
    Библиотека состоит из кучки dll, часть из которых содержит COM и нуждается в регистрации на машине. Той у нее вид из-за того, что надо держать на каждой машине две версии этой библиотеки.
    Инсталяция простая: от имени текущего пользователя запускается bat-файл, который копирует на машину файлы по списку и регистрит COM-библиотеки. Пока даем пользователям права на административно созданную для ПО папку, право писать в реестр (в его часть) и право регистрировать библиотеки COM-объектов (последние два права дает встроенная группа Power Users). Процесс установки автоматизирован: при запуске программы она проверяет наличие обновления и по необходимости запускает его сама.

    Когда будут появляться машины с Vista и W7, предвижу трудности. Хотелось бы заранее подумать над изменением архитектуры.
  • Программирование :: .NET технология от и до :: WinForms
  • Привет всем...
    У меня такая проблема: скачал класc для работы с COM портом (я так подозреваю, это класc MFC)
    Я сделал приложение в Windows Forms и пытаюсь в это приложение экспортировать этот класc следующим образом:

    extern "C" class __declspec (dllexport)  SerialGate
    {    
    public:
        
        enum IN_LINES_NAME {CTS, DSR, RING, RLSD};
        enum OUT_LINES_NAME {DTR, RTS};    
     
        SerialGate();
        ~SerialGate();    
     
        bool Open(int port, int baud);    
        int Send(char* buff, int szBuff);
        int Recv(char* buff, int szBuff);    
        void SetLine(OUT_LINES_NAME ln, bool state);
        bool GetLine(IN_LINES_NAME ln);
        void GetPortsInfo(PortInfo* pi);
        void Close();
        void Clean();
     
    private:
        HANDLE m_hFile;
        bool state;
    };
     
    и компилятор по этому поводу ругается...
    Подскажите синтаксис экспорта/импорта классов, функций из DLL, искал на MSDN, так по поводу импорта в FORMах ничего нет (или плохо искал)....
  • Программирование :: С/С++
  • Добрый день весельчяки! Подскажите, пожалуйста, что я делаю и понимаю не так
    Копирую значения из одного массива во временный, чтобы у меня остались старые значения, потом в первоначальный новые копирую и у меня во временном тоже изменяются значения на новые. Почему так происходит? Адреса в памяти массивов совпадают что-ли?
    Код:
    //файл С
    double B[500][6], BH4[500][6];

    //файл С++
    extern "C" double B[500][6], BH4[500][6];
    double tempB[500][6];

    void LoadBH4(void);

    void LoadH4(void)
    {
      memcpy(tempB,B,sizeof(tempB));
      memcpy(B,BH4,sizeof(B));  // значения в tempB тоже меняются на значения BH4 !!!!  :-/
    }

    Как мне сохранить временно первоначальные значения массива B ? (можно конечно вывести в файл, не спорю, но можно как-нибудь обойтись без этого?)
  • Объясните, как можно реализовать данную задумку. Есть, к примеру, следующий класс:
    Код:
    extern int f(int value);
    class A
    {
    int m_value;
    public:
    void SetValue(int value){m_value=f(value);}
    int GetValue()const{return m_value;}
    };
    Хотелось бы организовать чтение и изменение значение члена-класса m_value через одну функцию, что-нибудь на подобиe:
    Код:
    A a;
    a.Value():=3;
    Как это можно сделать???
  • Программирование :: С/С++ :: ANSI С/С++
  • В общем, я малость запутался.

    Есть некий тип-структура, имеющий в своем составе какой-либо STL-объект.
    Я передаю такую структуру по указателю в конструктор класса.
    В конструкторе делается копия в член класса, изменение оригинала и, при определенных условиях, копирование в обратную сторону - копия из члена класса в указатель.

    Код:
    typedef struct _struct1_t
    {
      // .....
    } struct1_t;

    typedef std::vector<struct1_t> list_struct1_t;

    typedef struct _struct2_t
    {
      list_struct1_t list;
    } struct2_t;

    class class1
    {
    private:
      struct2_t *p, copy;
    public:
      class1(struct2_t *p);
      void onExit(void);
    };

    class1::class1(struct2_t *p)
    {
      this->p = p;
      copy = *p;
    }

    void class1::onExit(void)
    {
      if (....)
        *p = copy;
    }

    Вопрос вот в чем: нет ли тут каких подвохов, если сработает код в onExit()?
    Код:
        *p = copy;

    Вроде бы не должно, но я не уверен. Под вечер мозг немного скрючился и туго думает.
  • Программирование :: С/С++ :: WinAPI & Visual C++
  • Не могу понять, почему так работает
    Код:
    char* pPathToINI = new char[MAX_LENGTH];                                  
    ...
    {
      ...                                                                         
      char* pBuffer = new char[MAX_LENGTH];                                   
      pBuffer = GetCurrentPath(pBuffer);                                     
      lstrcpy(pPathToINI,pBuffer);
    }                                                                         
    char* pFullPathToINI = lstrcat(pPathToINI,INIFILE);     



    А вот так - нет, компилятор ругается благим матом.
    Код:
    char* pPathToINI = new char[MAX_LENGTH];         
                            
    ...                                                                         
    {                                                                         
      ...
      char* pBuffer = new char[MAX_LENGTH];                                   
      pBuffer = GetCurrentPath(pBuffer);                                     
      lstrcpy(pPathToINI,pBuffer);                                           
    }                                                                         
    char* pFullPathToINI;
    pFullPathToINI = lstrcat(pPathToINI,INIFILE);

    В первом случае(когда работает) происходит инициализация pFullPathToINI адресом указателя pPathToINI.
    Во втором - pFullPathToINI присваивается адрес указателя pPathToINI.
    В MSDN по поводу lstrcat написано: If the function succeeds, the return value is a pointer to the buffer. Т.е. буфер на pPathToINI.
    Можно конечно оставить первый вариант, ноя хочу разобраться, почему второй не работает.

    Может кто-нибудь объяснить?

    Вот так ругается компилятор:
    Links.cpp|29|error C2501: 'pFullPathToINI' : missing storage-class or type specifiers|
    Links.cpp|29|error C2040: 'pFullPathToINI' : 'int' differs in levels of indirection from 'char *'|
    Links.cpp|29|error C2440: 'initializing' : cannot convert from 'char *' to 'int'|
    ||=== Build finished: 3 errors, 0 warnings ===|
  • Здравствуйте!
    Скачал недавно пример многопоточного клиент серверного приложения, пытаюсь разобраться что к чему и немного модифицировать

    Ошибка возникает когда подключается больше 2х клиентов: один из клиентов не обменивается данными с сервером, хотя другие работают нормально....

    Вот сервер
    Код:
    #include "stdafx.h"

    #define MY_PORT 666 // Порт, который слушает сервер

    // прототип функции, обслуживающий
    // подключившихся пользователей
    DWORD WINAPI SexToClient(LPVOID thread_info);

    // глобальная переменная – количество
    // активных пользователей
    int nclients = 0;

    struct ThreadInfo
    {
    SOCKET client_socket;
    HANDLE mutex;
    };

    int _tmain(int argc, _TCHAR* argv[])
    {
    using namespace std;
    setlocale(LC_ALL, "Russian");

    WSADATA wsadata;
    cout << "TCP SERVER DEMO" << endl;

    if (WSAStartup(0x0202, &wsadata))
    {
    // Ошибка!
    cout << "Error WSAStartup " << WSAGetLastError() << endl;
    return -1;
    }

    SOCKET mysocket;

    if ((mysocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
    // Ошибка!
    cout << "Error socket" << WSAGetLastError() << endl;
    WSACleanup();
    // Деиницилизация библиотеки Winsock
    return -1;
    }

    sockaddr_in local_addr;
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(MY_PORT);
    local_addr.sin_addr.s_addr = 0;

    if (bind(mysocket, (sockaddr *) &local_addr, sizeof(local_addr)))
    {
    // Ошибка
    cout << "Error bind " << WSAGetLastError() << endl;
    closesocket(mysocket);  // закрываем сокет!
    WSACleanup();
    return -1;
    }

    if (listen(mysocket, 0x100))
    {
    // Ошибка
    cout << "Error listen " << WSAGetLastError();
    closesocket(mysocket);
    WSACleanup();
    return -1;
    }

    cout << "Ожидание подключений" << endl;

    //SOCKET client_socket; 
    sockaddr_in client_addr;

    int client_addr_size = sizeof(client_addr);

                //ввожу i для задержки, чтобы успеть запустить несколько клиентов
    int i = 0;
    cin >> i;
    cout << i << endl;

    ThreadInfo thd_info;
    thd_info.mutex = CreateMutex(NULL, false, NULL);

    while(thd_info.client_socket = accept(mysocket, (sockaddr*) &client_addr, &client_addr_size))
    {
    nclients++;// увеличиваем счетчик подключившихся клиентов

    // пытаемся получить имя хоста
    HOSTENT* hst = gethostbyaddr((char*) &client_addr.sin_addr.s_addr, 4, AF_INET);

    // вывод сведений о клиенте
    cout << hst->h_name << inet_ntoa(client_addr.sin_addr) << " new connect!" << endl;

    DWORD thID;
    HANDLE my_thread = CreateThread(NULL, NULL, SexToClient, &thd_info, NULL, &thID);
    CloseHandle(my_thread);
        }

    return 0;
    }

    DWORD WINAPI SexToClient(LPVOID thread_info)
    {
    SOCKET my_sock = ((ThreadInfo*) thread_info)->client_socket;
    char buff[64];

    // цикл эхо-сервера: прием строки от клиента и возвращение ее клиенту
    int bytes_recv = 0;
    while( (bytes_recv = recv(my_sock, buff, sizeof(buff), 0)) && bytes_recv != SOCKET_ERROR)
    send(my_sock, buff, bytes_recv, 0);

    // если мы здесь, то произошел выход из цикла по причине возращения функцией recv ошибки – соединение клиентом разорвано
    if(WaitForSingleObject(((ThreadInfo*) thread_info)->mutex, INFINITE) == WAIT_OBJECT_0)
    {
    --nclients; // уменьшаем счетчик активных клиентов
    std::cout << "-disconnect, clients: " << nclients << std::endl;
    }
    else
    {
    std::cout << "wait" << std::endl;
    }

    ReleaseMutex(((ThreadInfo*) thread_info)->mutex);

    // закрываем сокет
    closesocket(my_sock);
    return 0;
    }

    Сначала запускаю сервер, затем несколько клиентов, после чего ввожу i для начала работы сервера.
    Только 2 клиента принимают и передают инфу, остальные не делают ничего....

    Вот клиент
    Код:
    #include "stdafx.h"

    #define PORT 666
    #define SERVERADDR "127.0.0.1"
    #define BUFF_SIZE 64

    int main(int argc, char* argv[])
      {
    using namespace std;

    char buff[BUFF_SIZE];

    cout << "TCP DEMO CLIENT" << endl;

    WSADATA wsadata;

    if (WSAStartup(0x202, &wsadata))
    {
    cout << "WSAStart error " << WSAGetLastError() << endl;
    return -1;
    }

    SOCKET my_sock;

    my_sock = socket(AF_INET,SOCK_STREAM,0);

    if (my_sock < 0)
    {
    cout << "Socket() error " << WSAGetLastError() << endl;
    return -1;
    }

    sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port=htons(PORT);
    HOSTENT *hst;


    if (inet_addr(SERVERADDR) != INADDR_NONE)
    dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR);
    else

    if (hst = gethostbyname(SERVERADDR))// hst->h_addr_list содержит не массив адресов, а массив указателей на адреса
    ((unsigned long *)&dest_addr.sin_addr)[0] = ((unsigned long **)hst->h_addr_list)[0][0];
    else
    {
    cout << "Invalid address " << SERVERADDR << endl;
    closesocket(my_sock);
    WSACleanup();
    return -1;
    }

    if (connect(my_sock, (sockaddr *)&dest_addr, sizeof(dest_addr)))
    {
    cout << "Connect error " << WSAGetLastError() << endl;
    return -1;
    }

    cout << "Connection with " << SERVERADDR << " successful complete" << endl;


    int nsize;

    for(int i = 0; i < 10; i++)
    {
    send(my_sock, "Hallow, server!", sizeof("Hallow, server!"), 0); //передаем строку клиента серверу

    if((nsize = recv(my_sock, buff, sizeof(buff) - 1, 0)) == SOCKET_ERROR)
    {
    //некорректный выход
    cout << "Recv error " << WSAGetLastError() << endl;
    closesocket(my_sock);
    WSACleanup();
    return 0;
    }

    // выводим на экран
    cout << i << ": " << buff << endl;

    Sleep(2000);
    }

    cout << "Exit..." << endl;
    closesocket(my_sock);
    WSACleanup();
    return -1;
    }

    Подскажите, пожалуйста, в чем ошибка и скажите, правильно ли я организовал блокировку в сервере
  • Если откомпилировать два абсолютно одинаковых C++ проекта, содержащих, например, вот такой код:

    Код:
    CUIntArray a;
      CUIntArray b = a;

    в студии 2003 (она же 7.1) и в 2005 (она же 8), то в первом случае получаем ошибку:
    Код:
    <путь к файлу>\имя файла.cpp(34) : error C2558: class 'CUIntArray' : no copy constructor
    available or copy constructor is declared 'explicit'

    с точным указанием строки содержащей ошибочный код.

    В 2005-ой студии получаем общее описание ошибки:

    Код:
    c:\programme\microsoft visual studio 8\vc\atlmfc\include\afxcoll.h(360) : error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'
    1>        c:\programme\microsoft visual studio 8\vc\atlmfc\include\afx.h(558) : see declaration of 'CObject::CObject'
    1>        c:\programme\microsoft visual studio 8\vc\atlmfc\include\afx.h(529) : see declaration of 'CObject'
    1>        This diagnostic occurred in the compiler generated function 'CUIntArray::CUIntArray(const CUIntArray &)'

    Студия 9 (2008) аналогично:

    Код:
    1>c:\program
    files\microsoft visual studio 9.0\vc\atlmfc\include\afxcoll.h(357) : error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'
    1>        c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(561) : see declaration of 'CObject::CObject'
    1>        c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\afx.h(532) : see declaration of 'CObject'
    1>        This diagnostic occurred in the compiler generated function 'CUIntArray::CUIntArray(const CUIntArray &)'

    и никакого намёка на место с ошибкой в проекте.

    В чём проблема? Баг студий начиная с версии 8 (2005)? Неправильные настройки? Кривые ручки? Кроче вопрос: как заставить новые студии показывать ошибку в коде, как это делала студия 2003 (7.1)?



    Ещё раз подчёркиваю - отвечать на непоставленный вопрос "как исправить ошибку?" не надо.

    ps Алик примерно так?
  • Здравствуйте, впервые столкнулся с необходимостью написания графического интерфейса на Win32 API, пойском искал, но ничего конкретного не нашел.

    Вопрос заключается вот в чем: "Как сделать ToolBar со своими(нарисованными вручную) кнопками?"

    Буду благодарен за любую информацию по данному вопросу... Среда разработки VS2008
  • Привет.

    Собственно весь вопрос - как ? Может быть есть сервисные функции о которых я не знаю?
  • Программирование :: С/С++ :: Borland C/C++
  • Хочу удалить подстроку из переменной типа AnsiString (это борландовский C++ аналог для паскалевских строк).

    В доке описано так:
    Цитировать
    Removes a specified number of characters from the string.

    AnsiString& __fastcall Delete(int index, int count);

    Description
    Delete modifies the AnsiString to remove count characters from the string beginning with the character at index, where 1 is the index of the first character. It returns the resulting modified string (*this).
    If index is larger than the length of the AnsiString or less than 1, no characters are deleted.
    If count specifies more characters than remain starting at the index, Delete removes the rest of the string. If count is less than 0, no characters are deleted.

    Делаю так:

    Код:
    Edit1->Text = "abc";
    Edit1->Text.Delete(3, 1);

    В итоге, в Edit1->Text по прежнему "abc".

    Кто-либо сталкивался с этим?

    У меня задача перебирать символы с конца строки, проверять по некому условию и удалять если проверка не пройдена.
  • Пользуюсь компонентами "Direct Oracle Access 405" для доступа к Oracle из BCB6.
    Заинтересовался вопросом, как можно в переменную подстановки передать значение NULL.

    Типичная передача не-NULL значения:
    Код:
      TDate someDate;

      OracleQuery->DeclareAndSet("SOME_DATE", otDate, someDate);
      // ...

    Что-то не могу найти в доках, как подставить NULL.

    Описание функции DeclareAndSet (для BCB и Delphi используется одна и та же библиотека и примеры в доке даны для Delphi):
    Код:
    procedure DeclareAndSet(Name: string; Type: Integer; Value: Variant);

    Тип Varaint может содержать след. типы:
    ∙   short
    ∙   int
    ∙   float
    ∙   double
    ∙   Currency
    ∙   TDateTime (TDate автоматически приводится к TDateTime)
    ∙   bool
    ∙   WordBool
    ∙   Byte
    ∙   AnsiString&
    ∙   char *
    ∙   wchar_t * const
    ∙   Ole2::IDispatch* const
    ∙   Ole2::IUnknown* const

    Т.е. никаких намеков на то, как закодировать NULL. Тем более, что TDate в своей основе - float, и NULL тут никак не выйдет.

    Есть такое понятие как "substitution variables", но заменять дату на подстановку некошерно и не хотелось бы - может получиться Ж при иной настройке NSL на клиентской машине.
  • Программирование :: VisualBasic
  • В общих чертах... Необходимо создать массив из 14 элементов, его значения - это круги семи цветов, формируются случайным образом... Необходимо сжать массив, выбросив из него элементы чёрного цвета. в отсутствии таковых - выдать сообщение о невозможности операции...

    Код:
    Dim color(14) As Integer
    Dim colorNotBlack(14) As Integer

    Private Sub Mass_rnd()
    Randomize

    Dim i As Integer
    For i = 0 To 14
    color(i) = Int(14 * Rnd)
    Next i
    End Sub

    Private Sub Draw()
    Mass_rnd
    Dim i As Integer
    Picture1.Fillstyle="0"
    Picture1.Scale (0, 0)-(20, 10)
    For i = 0 To 14
    Select Case color(i)
    Case 1
    Picture1.FillColor = 16776960
    Case 2
    Picture1.FillColor = 255
    Case 3
    Picture1.FillColor = 65280
    Case 4
    Picture1.FillColor = 65535
    Case 5
    Picture1.FillColor = 16711680
    Case 6
    Picture1.FillColor = 16777215
    Case 7
    Picture1.FillColor = 16711935
    Case 8, 9, 10, 11, 12, 13, 14
    Picture1.FillColor = 0
    End Select
    Picture1.Circle (1 + 1 * i, 5), 0.3
    Next i
    End Sub

    Private Sub Command1_Click()
    Draw
    Picture2.Cls
    End Sub

    Private Sub Command2_Click()
    Picture2.Fillstyle="0"
    Dim i As Integer
    Dim b As Integer
    b = 0
    For i = 0 To 14
    If color(i) >= 8 Then
    b = b + 1
    Помогите, как далее реализовать сжатие массива со смещением всех кругов к левому краю в Picture2??????
  • Программирование :: Ассемблер
  • Следующая программа осуществляет переход из реального режима в защищенный и обратно, при этом на экране должно выводиться слово "Hello". Однако слово не выводится. Программа должна работать в Windows XP. Может ли кто-то помочь? Заранее спасибо.
    P.S Отладка программы делается командами:
    tasm /m name.asm
    tlink /x/3 name.obj

    Код:
    .386p
    data segment 'data' use16
    message db 'H',7,'e',7,'l',7,'l',7,'o',7
    message_1=$-message
    rest_scr=25*80
    GDT label byte
    db 8 dup(0)
    GDT_flatCS db 0FFh,0FFh,0,0,0,10011010b,11001111b,0
    GDT_flatDS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0
    GDT_16bitCS db 0FFh,0FFh,0,0,0,10011010b,0,0
    GDT_16bitDS db 0FFh,0FFh,0,0,0,10010010b,0,0
    GDT_1=$-GDT
    gdtr dw GDT_1-1
    dd ?
    data ends

    RM_seg segment para public 'code' use16
    assume CS:RM_seg,SS:RM_stack,ds:data
    start:
    mov ax,data
    mov ds,ax
    in al,92h
    or al,2
    out 92h,al
    xor eax,eax
    mov ax,PM_seg
    shl eax,4
    add eax,offset PM_entry
    mov dword ptr cs:pm_entry_off,eax
    xor eax,eax
    mov ax,ds
    shl eax,4
    push eax
    mov word ptr GDT_16bitDS+2,ax
    shr eax,16
    mov byte ptr GDT_16bitDS+4,al
    xor eax,eax


    mov ax,cs
    shl eax,4
    mov word ptr GDT_16bitCS+2,ax
    shr eax,16
    mov byte ptr GDT_16bitCS+4,al
    pop eax
    add eax,offset GDT
    mov dword ptr gdtr+2,eax
    lgdt fword ptr gdtr
    cli
    in al,70h
    or al,80h
    out 70h,al
    mov eax,cr0
    or al,1
    mov cr0,eax
    db 66h
    db 0EAh
    pm_entry_off dd ?
    dw SEL_flatCS
    RM_return:
    mov eax,cr0
    and al,0FEh
    mov cr0,eax
    db 0EAh
    dw $+4
    dw RM_seg
    in al,70h
    and al,07FH
    out 70h,al
    sti
    mov ah,0
    int 16h
    mov ah,4Ch
    int 21h
    SEL_flatCS equ 00001000b
    SEL_flatDS equ 00010000b
    SEL_16bitCS equ 00011000b
    SEL_16bitDS equ 00100000b
    RM_seg ends

    PM_seg segment public 'CODE' use32
    assume cs:PM_seg
    PM_entry:
    mov ax,SEL_16bitDS
    mov ds,ax
    mov ax,SEL_flatDS
    mov es,ax
    mov edi,0B8000h
    mov ecx,rest_scr
    mov ax,720h
    rep stosw
    mov esi,offset message
    mov edi,0B8500h
    mov ecx,message_1
    rep movsb
    db 0EAh
    dd offset RM_return
    dw SEL_16bitCS
    PM_seg ends

    RM_stack segment stack 'STACK' use16
    db 100h dup(?)
    RM_stack ends
    end start
  • Программирование :: Программирование 1С
  • Народ, как как сделать информационную строку из подчинённого справочника?
    Имеется, например, справочник "клиенты", для него есть подчинённый справочник "должники" (в нём показываeся, что должен клиент). Вот как сделать, чтобы в обычной строке, которая находится в "клиентах", показывалось наименование справочника "должники"?
  • Добрый день!
    Подскажите, как реализовать проверку, записал ли пользователь мобильный контрагента?
    Вот на этом рисунке привожу эту форму: http://clip2net.com/page/m0/2635965

    Сам я хотел сделать, чтобы при открытии формы, сразу спрашивал телефон у пользователя, и тот тогда в любом случае не забывал бы и написал телефон. Но код, который не работает =(
    Код:
    Код:
    перем ТелКонтр;
     // Переменная, в которой будет храниться значение телефона контрагента
     

    ВвестиСтроку(ТелКонтр, "Введите телефон КонтрАгента", 15);
        
        РегСведений = РегистрыСведений.КонтактнаяИнформация;
        Запись = РегСведений.СоздатьМенеджерЗаписи();
        Запись.Объект = ЭтотОбъект.Ссылка;
        Запись.Вид = "Телефон контрагента";
        Запись.Представление = ТелКонтр;
        Запись.Записать(Истина);


    Потом поразмыслил и попытался другим путём пойти, поискал на форумах и нашел такой код, поставив его в "Процедура ПередЗаписью(Отказ)", но не понял, какие в него переменные запихать, и тот не заработал... =(

    Код:
    Код:
    Если НЕ обЗначениеНеЗаполнено(Тлф_) Тогда
                   МенеджерЗаписи = РегистрыСведений.КонтактнаяИнформация.СоздатьМенеджерЗаписи();
                   МенеджерЗаписи.Период    = НачалоГода(ТекущаяДата());
                   МенеджерЗаписи.Объект    = НовыйЭлемент_.Ссылка;
                   МенеджерЗаписи.Вид        = "Телефон контрагента";
                   //МенеджерЗаписи.Тип        = Перечисления.ТипыКонтактнойИнформации.МестныйТелефон;
     
                   МенеджерЗаписи.Тип        = Перечисления.ТипыКонтактнойИнформации.Телефон;
                   МенеджерЗаписи["Представление"] = Тлф_;
                   МенеджерЗаписи["Комментарий"] = Тлф_;
                   МенеджерЗаписи.Записать(Истина);
               КонецЕсли;



    Спасибо за любую помощь! Все мы когда-то учились  ;)
  • Программирование :: Программирование 1С :: 1С 7.x
  • У объекта типа "таблица" есть метод опции()

    Код:
    Таб = СоздатьОбъект("Таблица");
    ...
    Таб.Опции();

    Один из параметров:
    <ИмяОпцийПечати> - строковый идентификатор набора опций печати (необязателен, умолчание - пустая строка, в этом случае используются системные опции печати по умолчанию).

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

  • Программирование :: Программирование 1С :: 1С 8.x
  • Есть такая процедура:
    Код:
     Запрос=Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | РасчетПенсии.Контрагент,
    | РасчетПенсии.Пенсия,
    | НакопленияКонтрагентовОстатки.Контрагенты,
    | НакопленияКонтрагентовОстатки.СуммаОстаток
    |ИЗ
    | Документ.РасчетПенсии КАК РасчетПенсии,
    | РегистрНакопления.НакопленияКонтрагентов.Остатки КАК НакопленияКонтрагентовОстатки ГДЕ Контрагенты=РасчетПенсии.Контрагент";
    Результат = Запрос.Выполнить().Выбрать();
    Выплаты.Очистить();
    Пока Результат.Следующий() > 0  Цикл
    Выплаты.Добавить();
    ЕСЛИ Результат.СуммаОстаток<Результат.Пенсия ТОГДА
    Выплаты.ЗаполнитьЗначения(Результат.Контрагент,"Контрагент");
    Выплаты.ЗаполнитьЗначения(Результат.Пенсия,"КВыплате");
    Выплаты.ЗаполнитьЗначения(Результат.СуммаОстаток,"ОстатокСчета");
    Иначе
    Выплаты.ЗаполнитьЗначения(Результат.Контрагент,"Контрагент");
    Выплаты.ЗаполнитьЗначения(Результат.Пенсия,"КВыплате");
    Выплаты.ЗаполнитьЗначения(Результат.СуммаОстаток,"ОстатокСчета");
    КонецЕсли;
    КонецЦикла; 


    При ее выполнении в табличную часть добавляются несколько строк, но в каждую одно и то же значение последнего документа.
    Подскажите как сделать чтобы в строках были все документы, а не один и тот же.

    ЗЫ: и сразу вдогонку  :mrgreen: программированием 1с занимаюсь третий день только, по этому почти ничего не знаю. Подскажите, пожалуйста, как-то можно оптимизировать эту процедуру? Больше чем уверен, что в данном виде при большом количестве контрагентов, все будет жутко тормозить :)
  • Процедура Отчет(ТабДок, Период) Экспорт
        Макет = ВнешнийОтчетОбъект.ПолучитьМакет("Отчет");
        Запрос = Новый Запрос;
        Запрос.Текст =  
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |    УсловныеЦеныКонтрагентов.ДоговорКонтрагента.Владелец.Ссылка КАК ДоговорКонтрагентаВладелецСсылка,
        |    УсловныеЦеныКонтрагентов.ДоговорКонтрагента.Владелец.Представление,
        |    УсловныеЦеныКонтрагентов.ДоговорКонтрагента.ЦенаВключаетНДС,
        |    УсловныеЦеныКонтрагентов.КоэффициентЖира КАК КоэффициентЖира,
        |    УсловныеЦеныКонтрагентов.КоэффициентБелка КАК КоэффициентБелка,
        |    УсловныеЦеныКонтрагентов.ДоговорКонтрагента КАК ДоговорКонтрагента,
        |    УсловныеЦеныКонтрагентов.УсловнаяЦена КАК УсловнаяЦена,
        |    УсловныеЦеныКонтрагентов.Период КАК период,
        |    ВЫБОР
        |        КОГДА УсловныеЦеныКонтрагентов.ДоговорКонтрагента.ЦенаВключаетНДС
        |            ТОГДА УсловныеЦеныКонтрагентов.УсловнаяЦена / 100 * 10
        |        ИНАЧЕ 0
        |    КОНЕЦ КАК УсловнаяЦенаНДС
        |ИЗ
        |    РегистрСведений.УсловныеЦеныКонтрагентов КАК УсловныеЦеныКонтрагентов
        |ГДЕ
        |    УсловныеЦеныКонтрагентов.ДоговорКонтрагента.Владелец В ИЕРАРХИИ(&Владелец)
        |
        |УПОРЯДОЧИТЬ ПО
        |    период
        |ИТОГИ ПО
        |    ДоговорКонтрагентаВладелецСсылка ИЕРАРХИЯ";
     
        Запрос.УстановитьПараметр("Владелец", Владелец);
        Запрос.УстановитьПараметр("Период", Период);
     
        Результат = Запрос.Выполнить();
     
    Период это даты в договорах
     
    мне нужно в зависимости от даты в договоре выводить число с начало года!
     
    т.е. если дата 01.01.09 то это номер 1 соответственно следующая дата это 2 и так далее до даты в отчете
     
    по количеству записей т.е. если в договоре записи 05.01.09, 21.03.09, 26.06.09
    то на 26.06.09 это будет цифра 3, а на 21.03.09 это цифра 2 ну и так далее...

    как программно это описать?
  • Подскажите, как избавиться от горизонтальной полосы прокрутки в макете. Знаю, что у Табличного поля есть свойство
    ГоризонтальнаяПолосаПрокрутки, но не могу получить к нему доступ в коде:


    Код:
    ТабДокумент = Новый ТабличныйДокумент;    
        Макет = Документы.СчетНаОплатуПокупателю.ПолучитьМакет("АктЕДС");
    ТабДокумент.Вывести(Подвал);
    Область = Макет.ПолучитьОбласть("Заголовок");
        ТабДокумент.Вывести(Область);
        ТабДокумент.ОтображатьСетку = Ложь;
        ТабДокумент.Защита = Ложь;
        ТабДокумент.ТолькоПросмотр = Ложь;
        ТабДокумент.ОтображатьЗаголовки = Ложь;
        ТабДокумент.ИмяПараметровПечати="ПараметрыПечати";
        ТабДокумент.ИмяСохраненияПоложенияОкна="ПоложениеОкна";
        ТабДокумент.СохранятьСвойстваОтображения=Истина;
        ТабДокумент.ФиксацияСверху=10;
        ТабДокумент.Показать();

  • Здравствуйте!!!
    Есть Справочник Операторы. Содержит перечень мобильных операторов, телефоны которых есть на учете компании.
    Меня интересует, как сделать, чтоб отображало именно вот это вот "есть на учете" :shuffle:
  • Как сделать, чтоб в форме списка в отдельной колонке выводить все телефоны, которыми владеет человек(через запятую). :shuffle:
    Вся информация есть - телефоны, физические лица....
  • Есть справочник Пользователи. Содержит информацию о пользователях базы, используется в основном для указания ответственного в документах. Создается системой при первом входе пользователя в систему.  :confused:
    Я только начинаю программить на 1С 8.1. Помогите, пожалуйста, с последней частью задания - как сделать, чтоб создавалось при первом входе?  :dontknow:
  • Справочники:
           Телефоны. Содержит перечень мобильных телефонов, стоящих на учете компании. Подчинень соответствующему префиксу (который присутствует в номере).
      Реквизиты:
           Владелец - Тип: Справочник.Префиксы;
           Наименование - длина 0;
           Код - Тип: Строка; длина 10; Точность 0;
                    Вводится только значение номера без префикса (например, номер 0631234567, будет "063" - префикс, а код - "1234567").
      Форма:
           На форме элемента должно быть видно, какому оператору (информативно) и префиксу принадлежит номер, а также какому сотруднику он выдан (информация берется с регистра сведений "Владельцы телефонов"). В уже записанном элементе нельзя изменять префикс. В форме списка, в левой части должно быть дерево значений, в котором были бы перечислены все операторы и, как подчиненные им строки, префиксы. При выборе соответствующей строчки список телефонов должен соответственно фильтроваться (реализовать через Отбор в списке справочника).
  • Операционные системы :: Windows
  • Народ, кто пользовался, поделитесь впечатлениями?
    Собственно, интересует сравнение ее с Win XP. Собираюсь поставить посмотреть, что это и с чем его едят, хотелось бы послушать тех, у кого уже есть опыт. В данный момент у меня Win Xp Pro SP3 без MUI.
  • Направления программирования :: Drivers
  • Доброго всем времени суток...
    Появилась идейка связать компьютер и внешнее устройство (PIC18F4550) через USB шину (metod BUFFERED, тип передачи изохорный). От системы (PIC18F4550) требуется, для начала, получить (от хоста) и передать хосту 2 слова данных. С внешним устройством проблем нет (программой), а на компьютер есть.
    Драйверами начал заниматься где-то около месяца назад, прочитал умные книги : Агуров, Уолтер Они, и теперь в голове каша полная.
    Взял пример из DDK isoUSB за основу (правильно ли это?). На мой взгляд, там слишком много включено ненужных (необязательных) функций драйвера (так ли это?).
    Я уяснил, что есть обязательные функции: DriverEntry, DriverUnload, AddDevice.
    Рабочие процедуры регистрируются:

        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsoUsb_DispatchDevCtrl;
        DriverObject->MajorFunction[IRP_MJ_POWER]          = IsoUsb_DispatchPower;
        DriverObject->MajorFunction[IRP_MJ_PNP]            = IsoUsb_DispatchPnP;
        DriverObject->MajorFunction[IRP_MJ_CREATE]         = IsoUsb_DispatchCreate;
        DriverObject->MajorFunction[IRP_MJ_CLOSE]          = IsoUsb_DispatchClose;
        DriverObject->MajorFunction[IRP_MJ_CLEANUP]        = IsoUsb_DispatchClean;
        DriverObject->MajorFunction[IRP_MJ_READ]           =
        DriverObject->MajorFunction[IRP_MJ_WRITE]          = IsoUsb_DispatchReadWrite;
        DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = IsoUsb_DispatchSysCtrl;
        DriverObject->DriverUnload                         = IsoUsb_DriverUnload;
        DriverObject->DriverExtension->AddDevice           = (PDRIVER_ADD_DEVICE) IsoUsb_AddDevice;

    Скажите, все ли эти процедуры нужно включать в драйвер для моей будущей системы, если мне нужно просто передавать и принимать без  отслеживания и контроля транзакций, правильно ли будет ограничиться следующим набором рабочих процедур:

        DriverObject->MajorFunction[IRP_MJ_CREATE]         = IsoUsb_DispatchCreate;
        DriverObject->MajorFunction[IRP_MJ_CLOSE]          = IsoUsb_DispatchClose;
        DriverObject->MajorFunction[IRP_MJ_READ]           = IsoUsb_DispatchReadWrite;
        DriverObject->MajorFunction[IRP_MJ_WRITE]          = IsoUsb_DispatchReadWrite;
        DriverObject->DriverUnload                         = IsoUsb_DriverUnload;
        DriverObject->DriverExtension->AddDevice           = (PDRIVER_ADD_DEVICE) IsoUsb_AddDevice;

    Помогите "разложить все по полочкам".
    Конкретные вопросы будут потом.
    СПАСИБО.
  • Доброго времени суток, форумчане.

    Написал простенький драйвер-фильтр ФС.
    IRP'ы и FastIO запросы перехватываю, как по учебнику.  Чтение\запись..., ну и все остальное.

    Меня интересуют передаваемые данные от прикладной программы к драйверу.
    Проблемы (т.е. BSOD'ы) начинаются, когда пытаюсь их, данные, слегка модифицировать.


     Драйвера ФС в основном использут Nether Buffered Nor Direct I\O способ передачи данных от приложения к драйверу.
    То есть, мы, выполняясь в контексте приложения, получаем доступ к его памяти и шаманим :) с ней (модифицируя, копируя, сохраняя...)

    Первые два метода работы с буфером данных Buffered и Direct I\O пока не обрабатываем (только проверяем их использование).

    Опытным путем установил, что большинство запросов чтения\записи данных выполняется именно посредством FastIO.
    В обработчике FastIOWrite пишу следующее (в обработку IRP_MJ_READ\ IRP_MJ_WRITE решил пока не лезть - просто спускаю вниз), в тестовом режиме решил модифицировать исходный буфер только при обработке FastIOWrite

    Код:
    BOOLEAN  
    IntercepterFastIoWrite(
        IN PFILE_OBJECT FileObject,
        IN PLARGE_INTEGER FileOffset,
        IN ULONG Length,
        IN BOOLEAN Wait,
        IN ULONG LockKey,
        IN PVOID Buffer,
        OUT PIO_STATUS_BLOCK IoStatus,
        IN PDEVICE_OBJECT DeviceObject
        )
    {
       // ...
       // немного необходимой рутины по спусканию запроса вниз по стеку
       // ...
      
       DbgPrint (("Buff size: %i \n  buff: '%s'  ", Length, Buffer));
       int ModifOffset = 7; // ModifOffset < Length
       *((char*) Buffer + ModifOffset) = 'W';
      
      // ...
    }


    Для тестов быстренько написал простенькую программу, которая пишет в файл строку "Hello world" посредством CreateFile\WriteFile. Настроил фильтр так, чтобы он реагировал на запросы, отправляемые драйверу, только исходящие от этой программы.

     Хочу, чтобы в драфвере-фильтре буква 'w' заменилась на 'W' (world --> World), и как только я пытаюсь это делать -  BSOD, BSOD и еще раз BSOD :headbang:

     Если закомментировать
    Код:
      // int ModifOffset = 7; // ModifOffset < Length
      // *((char*) Buffer + ModifOffset) = 'W';
       
     
    все работает, и DbgPrint добросовестно выводит записываемую информацию....

    Что не так делаю? :confused:
  • Всем привет!
     Очень нуждаюсь в Вашей помощи, господа!
    В двух словах: конечная цель - в usb воткнуто нечто, и это нечто ОДНОВРЕМЕННО считывает значения сопротивления/напряжения  на нескольких (~4) элементах внешнего устройства. Все это отсылается в программу/драйвер на компьютере, производит вычисления и выдает какой-то конечный результат на мониторе. Откровенно признаться, знания в области программирования - поверхностные, хорошо подзабытые C++ и когда-то сам учил delphi (увы, не моя предметная область).  По аппаратной части тоже не знаю, с чего начать(.
    Пожалуйста, скажите с чего начать, где почитать, буду очень признателен. Сейчас купил Агурова .. тяжело идет(.

    Если правильно понимаю - для начала необходимо проработать железо на базе микроконтроллера?
  • Здравствуйте. Всем доброго времени суток.

    У меня есть кусочек кода.

    Код:
    ULONG  ncall = 0x019 // CloseHandle
    __declspec(naked)NTSTATUS
    __stdcall
    syscall(ULONG a1,ULONG a2,ULONG a3,)
    {
    __asm {
    mov eax, ncall
    call FastSystemCall
    ret 0xс
    FastSystemCall:
    mov edx, esp
    sysenter
    ret
    }   
    }

    Собсвенно вопрос: как поведет себя ядерный обработчик при таком  вызове
    Код:
    syscall(0x28,0xfadec0de,0xffffffff);

    Как я понимаю на обработку пойдет только первый аргумент(0x28),  второй и третий  будут "отброшены"?

  • Подскажите, пожалуйста, где можно прочитать про то, что должно быть в драйвере, чтобы он корректно работал с несколькими одинаковыми USB устройствами...

    Хотелось бы знать, как с уровня приложений:
    - получить список подключенных устройств;
    - как обратиться к конкретному устройству, т.е. как получить handle на конкретное устройство через тот же CreateFile.

    В настоящий момент для работы с USB устройством драйвер написан и успешно работает. Когда подключаю два устройства, Windows XP вылетает в синий экран...
    В лоб найти информацию про драйвера для одновременной работы с несколькими одинаковыми устройствами не получилось...
  • Всем привет!

    Может кто-то подскажет в какой среде можно удобно писать драйверы,

    и что-бы их можно было компилировать с самой среде?



    Спасибо!
  • Практические разделы :: Железо
  • пока решил сюда тему создать.

    Вопрос такой: кто пользовался микроконтроллером FT232BM
    ( это эмулятор ком порта, который работает через USB )

    пока так удочку закинул - чтобы найти, кому потом глупые вопросы позадавать )

    И имеется ли альтернативное решение, не только этот МК ?
  • Учимся программировать :: Начинающим
  • Скажите, пожалуйста, так верно?

    Код:
    Type **type;

    Alloc(int N, int M)
    {
       type=new Type[N];
       for(int i=0; i<N; i++)
       {
              type[i]=new Type[M];
       }
    }

    ...

    delete []type;
         

  • Привет! Я недавно начал изучать микроконтроллеры, почему-то не получается разобратся с LCD вот код, если в нем есть ошибка- укажите, буду благодарен  :)
    Код:
    #include "c8051F120.h"


    sbit LCD_rs=P2^2;
    sbit LCD_rw=P2^1;
    sbit LCD_en=P2^0;
    #define LCD_data P4

    void Port_IO_Init(void);
    void LCD_init(void);
    void LCD_command(unsigned char var);
    void LCD_busy(void);
    void LCD_senddata(unsigned char var);
    void LCD_sendstring(unsigned char *var);
    void LCD_build();


     void main (void)
      { 
       WDTCN     = 0xDE;
       WDTCN     = 0xAD;
       Port_IO_Init();
       LCD_init ();
       LCD_command ();
     
       LCD_sendstring ();
       LCD_build();
       LCD_busy();

       }
       
       void Port_IO_Init(void)
    {
        SFRPAGE   = CONFIG_PAGE;
        P2MDOUT   = 0xFF;
        P4MDOUT   = 0xFF;
        XBR2      = 0x40;

    }


    void LCD_init(void)
    {LCD_data = 0x0E;// 2 линии 8 бит 5х8 точек
     LCD_rs = 0;// обработка данных как инструкций
     LCD_rw = 0; // запись данных в ЖКИ
     LCD_en = 1;
     LCD_en = 0;
     LCD_busy(); //пауза для обработки команд
     LCD_data = 0x01;//включить дисплей, курсор
     LCD_rs  = 0;
     LCD_rw = 0;
     LCD_en = 1;
     LCD_en = 0;
     LCD_busy();
     LCD_data = 0x01;
     LCD_rs = 0;
     LCD_rw = 0;
     LCD_en = 1;
     LCD_en = 0;
     LCD_busy();
     LCD_data = 0x06;//режим введения авто увиличение без сдвига
     LCD_rs = 0;
     LCD_rw = 0;
     LCD_en = 1;
     LCD_busy();
     LCD_data = 0;
    }




    void LCD_busy()
    {unsigned char i,j;
    for(i=0;i<50;i++) //A simple for loop for delay
    for(j=0;j<255;j++);
    }
    void LCD_command(unsigned char var)
    {
     LCD_data = var;
     LCD_rs = 0;
     LCD_rw = 0;
     LCD_en = 1;
     LCD_en = 0;
     LCD_busy();
    }
    void LCD_sendstring(unsigned char *var)
    { while(*var) //till string ends
    LCD_senddata(*var++); //send characters one by one
    }

    void LCD_build()
    {
    LCD_command(0x48); //Load the location where we want to store
    LCD_senddata(0x04); //Load row 1 data
    LCD_senddata(0x0E); //Load row 2 data
    LCD_senddata(0x0E); //Load row 3 data
    LCD_senddata(0x0E); //Load row 4 data
    LCD_senddata(0x1F); //Load row 5 data
    LCD_senddata(0x00); //Load row 6 data
    LCD_senddata(0x04); //Load row 7 data
    LCD_senddata(0x00); //Load row
    }



    void LCD_senddata(unsigned char var)
    {
     LCD_data = var;
     LCD_rs = 1;
     LCD_rw = 0;
     LCD_en = 1;
     LCD_en = 0;
     LCD_busy();
    }
  • Hello world... С VS2008 ничего не вышло (даже интегрировать не смог)... Утилита Build рулит...
    У меня вот еще что: не могу откомпилить приложение, почему-то ругается "линковщик", ошибки: error LNK2019, error LNK2028,
    fatal error LNK1120
    В код, часом, ничего включать не нужно (какую-нибудь информацию о драйвере), Агуров вроде ничего не включал....

А теперь прощаемся с Вами до следующего выпуска.


С уважением, команда Клуба.


В избранное