flat assembler
Message board for the users of flat assembler.

Index > Windows > Shortest (size of code) macro for SINGLE INSTANCE

Thread Post new topic Reply to topic

Joined: 24 Mar 2012
Posts: 699
Location: Russian Federation, Sochi
ProMiNick 10 Feb 2018, 00:54
macro singleinstance _class*,_title*,exitjmp*,noextra {;(maybe ":0" instead "*" more wise for class & title)
        invoke  FindWindow,_class,_title
        or      eax,eax
  match any,noextra \{ jnz     exitjmp \}
  match ,noextra \{
  \local .init
        jz      .init
        push    SW_RESTORE
        push    eax
        call    [IsIconic]
        sub     esp,4
        or      eax,eax
        jz      @F
        call    [ShowWindow]
        jmp     exitjmp ;"jmp exitjmp" is more preferrable than "sub     esp,8", however any of them are valid here
        call    [SetForegroundWindow] 
        jmp     exitjmp 
  .init: \}

use case:
; Template for program using standard Win32 headers

format PE GUI 4.0
entry main.start

include 'win32w.inc'

section '.text' code readable executable
        invoke  GetModuleHandle,0
        mov     [hInstance],eax

        singleinstance _class,_title,.exit;,noactivating

        invoke  LoadCursor,0,IDC_ARROW ; Try to remove theese 2 lines
        mov     [wc.hCursor],eax ; and move cursor slowly from outer to the window, and you understand why they should never be skipped.

        invoke  RegisterClass,wc
        test    eax,eax
        jz      .error

        invoke  CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU+WS_MINIMIZEBOX,128,128,256,192,NULL,NULL,[hInstance],NULL
        test    eax,eax
        jz      .error

        invoke  GetMessage,msg,NULL,0,0
        cmp     eax,1
        jb      .exit
        jne     .msg_loop
        invoke  TranslateMessage,msg
        invoke  DispatchMessage,msg
        jmp     .msg_loop

        invoke  MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK

        invoke  ExitProcess,[msg.wParam]

proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam
        cmp     [wmsg],WM_DESTROY
        je      .wmdestroy
        invoke  DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]
        jmp     .finish
        invoke  PostQuitMessage,0
        xor     eax,eax

section '.data' data readable writeable
  label hInstance:dword at wc.hInstance ; no needed to create data members twice for same purpose
  _class TCHAR 'FASMWIN32',0
  _title TCHAR 'Win32 program template',0
  _error TCHAR 'Startup failed.',0


  msg MSG

section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',\

  include 'api\kernel32.inc'
  include 'api\user32.inc'    
so, you can forgot about manual realization of single instancing & just use macro fast & readable

I don`t like to refer by "you" to one person.
My soul requires acronim "thou" instead.
Post 10 Feb 2018, 00:54
View user's profile Send private message Send e-mail Reply with quote
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 19073
Location: In your JS exploiting you and your system
revolution 10 Feb 2018, 04:10
Using FindWindow is not guaranteed to be atomic or unique. Perhaps instead you can consider using a mutex. Mutexes are specifically designed for this sort of thing, they are guaranteed to give you a single instance.

Moving to Windows forum.
Post 10 Feb 2018, 04:10
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum

Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.